-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial impl. Not submitting correct vLEI data to vLEI verification s…
…ervice Signed-off-by: 2byrds <[email protected]>
- Loading branch information
Showing
20 changed files
with
427 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# base image | ||
FROM python:3.11-alpine | ||
|
||
# set working directory | ||
WORKDIR /usr/src/app/regps | ||
|
||
# add app | ||
COPY ./src /usr/src/app/regps/src | ||
COPY ./setup.py /usr/src/app/regps/setup.py | ||
COPY ./requirements.txt /usr/src/app/regps/requirements.txt | ||
|
||
# install requirements | ||
RUN pip install --no-cache-dir -r requirements.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# regulation-portal-service | ||
A service to manage regulator portal requests/responses that requires authentication, document submission, validation, and more | ||
|
||
## Desgin | ||
### Web app support | ||
The web app (UI front-end) will be using Signify/KERIA for selecting identifiers and credentials: | ||
|
||
### This service | ||
The regulation service will provide the ability to: | ||
* Login using an AID, SAID, and vLEI | ||
* Upload signed files | ||
* Check the status of an upload | ||
|
||
## Development | ||
You need to run a local vLEI service, see https://github.com/GLEIF-IT/reg-poc-verifier: | ||
```verifier server start --config-dir scripts --config-file verifier-config.json``` | ||
|
||
To start this web service: | ||
```docker-compose up -d --build``` | ||
To tear this web service: | ||
```docker-compose down``` | ||
|
||
You should see: | ||
```[+] Running 4/4 | ||
✔ Network reg-poc-server_default Created 0.1s | ||
✔ Container reg-poc-server-redis-1 Started 0.6s | ||
✔ Container web Started 0.8s | ||
✔ Container reg-poc-server-celery-1 Started | ||
``` | ||
|
||
You can run a test query using Swagger by going to: | ||
``` | ||
http://127.0.0.1:8000/api/doc# | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
version: '3.8' | ||
|
||
services: | ||
|
||
web: | ||
build: ./ | ||
image: web | ||
container_name: web | ||
ports: | ||
- 8000:8000 | ||
volumes: | ||
- ./:/usr/src/app/regps | ||
command: sh -c "cd src/regps/ && gunicorn -b 0.0.0.0:8000 app:app --reload" | ||
environment: | ||
- CELERY_BROKER=redis://redis:6379/0 | ||
- CELERY_BACKEND=redis://redis:6379/0 | ||
depends_on: | ||
- redis | ||
|
||
celery: | ||
image: web | ||
volumes: | ||
- ./:/usr/src/app/regps | ||
command: sh -c "cd src/regps/ && celery -A app.tasks worker --loglevel=debug" | ||
environment: | ||
- CELERY_BROKER=redis://redis:6379/0 | ||
- CELERY_BACKEND=redis://redis:6379/0 | ||
depends_on: | ||
- web | ||
- redis | ||
|
||
redis: | ||
image: redis:7-alpine |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# requirements.txt | ||
# Best practices for setup.py vs requirements.txt | ||
# https://caremad.io/posts/2013/07/setup-vs-requirement/ | ||
# https://pip.pypa.io/en/stable/reference/pip_install/#install-index-url | ||
|
||
# enables pip install -r requirements.txt to work with setup.py dependencies | ||
# pull the dependencies from setup.py for keri from pip index | ||
--index-url https://pypi.org/simple/ # pypi base pip index or local pip index | ||
|
||
--editable . # install as editable |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
#!/usr/bin/env python | ||
# -*- encoding: utf-8 -*- | ||
""" | ||
$ python setup.py register sdist upload | ||
First Time register project on pypi | ||
https://pypi.org/manage/projects/ | ||
Update sphinx /docs | ||
$ cd /docs | ||
$ sphinx-build -b html source build/html | ||
or | ||
$ sphinx-apidoc -f -o source/ ../src/ | ||
$ make html | ||
Best practices for setup.py and requirements.txt | ||
https://caremad.io/posts/2013/07/setup-vs-requirement/ | ||
""" | ||
|
||
|
||
from glob import glob | ||
from os.path import basename | ||
from os.path import splitext | ||
|
||
from setuptools import find_packages | ||
from setuptools import setup | ||
|
||
setup( | ||
name='reg-portal-service', | ||
version='0.0.1', # also change in src/regps/__init__.py | ||
license='Apache Software License 2.0', | ||
description='RegPS: Regulation Portal Service.', | ||
long_description="RegPS: A Regulation Portal Service to orchestate web app, vLEI validation, etc.", | ||
author='Lance Byrd', | ||
author_email='[email protected]', | ||
url='https://github.com/roots-id/regulation-portal-service', | ||
packages=find_packages('src'), | ||
package_dir={'': 'src'}, | ||
py_modules=[splitext(basename(path))[0] for path in glob('src/*.py')], | ||
include_package_data=True, | ||
zip_safe=False, | ||
classifiers=[ | ||
# complete classifier list: http://pypi.python.org/pypi?%3Aaction=list_classifiers | ||
'Development Status :: 3 - Alpha', | ||
'Intended Audience :: Developers', | ||
'License :: OSI Approved :: Apache Software License', | ||
'Operating System :: Unix', | ||
'Operating System :: POSIX', | ||
'Operating System :: Microsoft :: Windows', | ||
'Programming Language :: Python :: 3.10', | ||
'Programming Language :: Python :: Implementation :: CPython', | ||
# uncomment if you test on these interpreters: | ||
# 'Programming Language :: Python :: Implementation :: PyPy', | ||
# 'Programming Language :: Python :: Implementation :: IronPython', | ||
# 'Programming Language :: Python :: Implementation :: Jython', | ||
# 'Programming Language :: Python :: Implementation :: Stackless', | ||
'Topic :: Utilities', | ||
], | ||
project_urls={ | ||
'Issue Tracker': 'https://github.com/roots-id/regulation-portal-service/issues', | ||
}, | ||
keywords=[ | ||
"secure attribution", | ||
"authentic data", | ||
"regulatory compliance", | ||
"vLEI", | ||
# eg: 'keyword1', 'keyword2', 'keyword3', | ||
], | ||
python_requires='>=3.10.4', | ||
install_requires=[ | ||
'apispec>=6.3.0', | ||
'asyncio>=3.4.3', | ||
'celery>=5.3.0', | ||
'dataclasses_json>=0.5.7', | ||
'falcon>=3.1.0', | ||
'http_sfv>=0.9.8', | ||
'redis>=4.5.5', | ||
'requests>=2.31.0', | ||
'swagger-ui-py>=22.7.13', | ||
'gunicorn>=20.1.0', | ||
], | ||
extras_require={ | ||
# eg: | ||
# 'rst': ['docutils>=0.11'], | ||
# ':python_version=="2.6"': ['argparse'], | ||
}, | ||
tests_require=[ | ||
'coverage>=5.5', | ||
'pytest>=6.2.4', | ||
], | ||
setup_requires=[ | ||
], | ||
entry_points={ | ||
'console_scripts': [ | ||
'regps = regps.app.cli.regps:main', | ||
] | ||
}, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from app.service import falcon_app, swagger_ui | ||
|
||
print("Starting RegPS...") | ||
app = falcon_app() | ||
api_doc=swagger_ui(app) |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Empty file.
Binary file not shown.
Empty file.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# -*- encoding: utf-8 -*- | ||
""" | ||
Regulation portal service | ||
regps.cli.regps.commands module | ||
regulation portal servicecommand line interface | ||
""" | ||
import argparse | ||
|
||
# from regps.app import service | ||
|
||
d = "Runs regulation portal service\n" | ||
d += "\tExample:\nregps\n" | ||
parser = argparse.ArgumentParser(description=d) | ||
parser.set_defaults(handler=lambda args: launch(args)) | ||
parser.add_argument('-V', '--version', | ||
action='version', | ||
version="0.0.1", | ||
help="Prints out version of script runner.") | ||
parser.add_argument('-p', '--port', | ||
action='store', | ||
default=4902, | ||
help="Local port number the HTTP server listens on. Default is 4902.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# -*- encoding: utf-8 -*- | ||
""" | ||
Regulation portal service | ||
regps.app.cli.commands module | ||
""" | ||
import logging | ||
import multicommand | ||
import regps.app.service as service | ||
import commands | ||
|
||
def main(): | ||
parser = multicommand.create_parser(commands) | ||
args = parser.parse_args() | ||
|
||
if not hasattr(args, 'handler'): | ||
parser.print_help() | ||
return | ||
|
||
try: | ||
logging.info("******* Starting regulation portal service for %s listening: http/%s " | ||
".******", args.http) | ||
|
||
service.main(http=int(args.http)) | ||
|
||
logging.info("******* Ended reg portal service %s listening: http/%s" | ||
".******", args.http) | ||
|
||
|
||
except Exception as ex: | ||
print(f"ERR: {ex}") | ||
return -1 | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
# import asyncio | ||
# import falcon.asgi | ||
import falcon | ||
from falcon import media | ||
from falcon.http_status import HTTPStatus | ||
import json | ||
import os | ||
from swagger_ui import api_doc | ||
from app.tasks import verify | ||
# import uvicorn | ||
|
||
class LoginTask(object): | ||
|
||
def on_post(self, req, resp): | ||
print("LoginTask.on_post") | ||
try: | ||
raw_json = req.stream.read() | ||
result = json.loads(raw_json) | ||
print(f"LoginTask.on_post: result is {result}") | ||
result = verify(result['aid'], result['said'], result['vlei']) | ||
resp.status = result.status_code | ||
resp.text = result.text | ||
resp.content_type = result.content | ||
except Exception as e: | ||
print(f"LoginTask.on_post: Exception: {e}") | ||
resp.status = falcon.HTTP_500 | ||
|
||
|
||
class HandleCORS(object): | ||
def process_request(self, req, resp): | ||
resp.set_header('Access-Control-Allow-Origin', '*') | ||
resp.set_header('Access-Control-Allow-Methods', '*') | ||
resp.set_header('Access-Control-Allow-Headers', '*') | ||
resp.set_header('Access-Control-Max-Age', 1728000) # 20 days | ||
if req.method == 'OPTIONS': | ||
raise HTTPStatus(falcon.HTTP_200, body='\n') | ||
|
||
class PingResource: | ||
def on_get(self, req, resp): | ||
"""Handles GET requests""" | ||
resp.status = falcon.HTTP_200 | ||
resp.content_type = falcon.MEDIA_TEXT | ||
resp.text = ( | ||
'Pong' | ||
) | ||
|
||
def getRequiredParam(body, name): | ||
param = body.get(name) | ||
if param is None: | ||
raise falcon.HTTPBadRequest(description=f"required field '{name}' missing from request") | ||
|
||
return param | ||
|
||
def swagger_ui(app): | ||
cesr = None | ||
with open('app/data/credential.cesr', 'r') as file: | ||
file_contents = file.read() | ||
print("Loaded cesr cred data {}".format(file_contents)) | ||
config = {"openapi":"3.0.1", | ||
"info":{"title":"Regulator portal service api","description":"Regulator web portal service api","version":"1.0.0"}, | ||
"servers":[{"url":"http://127.0.0.1:8000","description":"local server"}], | ||
"tags":[{"name":"default","description":"default tag"}], | ||
"paths":{"/ping":{"get":{"tags":["default"],"summary":"output pong.","responses":{"200":{"description":"OK","content":{"application/text":{"schema":{"type":"object","example":"Pong"}}}}}}}, | ||
"/login":{"post":{"tags":["default"], | ||
"summary":"Given an AID and vLEI, returns information about the login", | ||
"requestBody":{"required":"true","content":{"application/json":{"schema":{"type":"object","properties":{ | ||
"aid":{"type":"string","example":"EBcIURLpxmVwahksgrsGW6_dUw0zBhyEHYFk17eWrZfk"}, | ||
"said":{"type":"string","example":"EPmiOgVewnJB8Oev8v4roUqIFNn5SBgiV-ukHiLW81ot"}, | ||
"vlei":{"type":"string","example":f"{file_contents}"} | ||
}}}}}, | ||
"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","example":{"status": "200 OK", "message": "AID and vLEI valid login"}}}}}} | ||
}} | ||
}, | ||
"components":{}} | ||
|
||
doc = api_doc(app, config=config, url_prefix='/api/doc', title='API doc', editor=True) | ||
return doc | ||
|
||
def falcon_app(): | ||
app = falcon.App(middleware=falcon.CORSMiddleware( | ||
allow_origins='*', allow_credentials='*', | ||
expose_headers=['content-type', 'signature', 'signature-input']) | ||
) | ||
# if os.getenv("KERI_AGENT_CORS", "false").lower() in ("true", "1"): | ||
app.add_middleware(middleware=HandleCORS()) | ||
print("CORS enabled") | ||
# app.add_middleware(authing.SignatureValidationComponent(agency=agency, authn=authn, allowed=["/agent"])) | ||
app.req_options.media_handlers.update(media.Handlers()) | ||
app.resp_options.media_handlers.update(media.Handlers()) | ||
|
||
# app = falcon.asgi.App() | ||
ping = PingResource() | ||
app.add_route('/ping', ping) | ||
app.add_route('/login', LoginTask()) | ||
|
||
return app | ||
|
||
# async def appl(scope, receive, send): | ||
# assert scope['type'] == 'http' | ||
|
||
# await send({ | ||
# 'type': 'http.response.start', | ||
# 'status': 200, | ||
# 'headers': [ | ||
# [b'content-type', b'text/plain'], | ||
# ], | ||
# }) | ||
# await send({ | ||
# 'type': 'http.response.body', | ||
# 'body': b'Hello, world!', | ||
# }) | ||
|
||
def main(first, second): | ||
print("Starting RegPS...") | ||
app = falcon_app() | ||
api_doc=swagger_ui(app) | ||
return app | ||
|
||
if __name__ == '__main__': | ||
main() |
Oops, something went wrong.