Merge pull request 'api-v2' (#1) from api-v2 into main
Reviewed-on: https://nextgenerations-cities.encs.concordia.ca/gitea/p_yefi/gamification_service_v2/pulls/1
This commit is contained in:
commit
ac776c4e5d
81
bootstrap.py
Normal file
81
bootstrap.py
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
"""
|
||||||
|
Main
|
||||||
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
|
Copyright © 2021 Project Author name guillermo.gutierrezmorote@concordia.ca
|
||||||
|
Project Collaborator name peteryefi@gmail.com
|
||||||
|
"""
|
||||||
|
|
||||||
|
import flask
|
||||||
|
from apispec import APISpec
|
||||||
|
from apispec.ext.marshmallow import MarshmallowPlugin
|
||||||
|
from flask_apispec.extension import FlaskApiSpec
|
||||||
|
from flask_restful import Api
|
||||||
|
from hub_api.city_info import CityInfo, City
|
||||||
|
from hub_api.geometry import Geometry
|
||||||
|
from hub_api.greenery_catalog import GreeneryCatalogEntries
|
||||||
|
from hub_api.greenery_catalog import GreeneryCatalogEntry
|
||||||
|
from hub_api.greenery_catalog import GreeneryCatalogNames
|
||||||
|
from hub_api.construction_catalog import ConstructionCatalogEntries
|
||||||
|
from hub_api.construction_catalog import ConstructionCatalogEntry
|
||||||
|
from hub_api.construction_catalog import ConstructionCatalogNames
|
||||||
|
from hub_api.usage_catalog import UsageCatalogEntries
|
||||||
|
from hub_api.usage_catalog import UsageCatalogEntry
|
||||||
|
from hub_api.usage_catalog import UsageCatalogNames
|
||||||
|
from hub_api.heat_pump import HeatPump
|
||||||
|
from hub_api.lca import MaterialLCACatalog
|
||||||
|
from hub_api.lca import MaterialLCACalculations
|
||||||
|
from hub_api.construction import Construction
|
||||||
|
from hub_api.usage import Usage
|
||||||
|
from hub_api.energy_demand import EnergyDemand
|
||||||
|
from hub_api.session import SessionStart, SessionEnd, KeepSessionAlive
|
||||||
|
from hub_api.uptime import Uptime
|
||||||
|
from hub_api.greenery import Greenery
|
||||||
|
from hub_api.user import User, UserLogin
|
||||||
|
|
||||||
|
app = flask.Flask('gamification')
|
||||||
|
api = Api(app)
|
||||||
|
|
||||||
|
|
||||||
|
api.add_resource(Uptime, '/v1.4/uptime')
|
||||||
|
api.add_resource(Geometry, '/v1.4/geometry')
|
||||||
|
api.add_resource(GreeneryCatalogEntry, '/v1.4/greenery-catalog/entry')
|
||||||
|
api.add_resource(GreeneryCatalogEntries, '/v1.4/greenery-catalog/entries')
|
||||||
|
api.add_resource(GreeneryCatalogNames, '/v1.4/greenery-catalog/names')
|
||||||
|
api.add_resource(ConstructionCatalogEntry, '/v1.4/construction-catalog/entry')
|
||||||
|
api.add_resource(ConstructionCatalogEntries, '/v1.4/construction-catalog/entries')
|
||||||
|
api.add_resource(ConstructionCatalogNames, '/v1.4/construction-catalog/names')
|
||||||
|
api.add_resource(Construction, '/v1.4/construction')
|
||||||
|
api.add_resource(UsageCatalogEntry, '/v1.4/usage-catalog/entry')
|
||||||
|
api.add_resource(UsageCatalogEntries, '/v1.4/usage-catalog/entries')
|
||||||
|
api.add_resource(UsageCatalogNames, '/v1.4/usage-catalog/names')
|
||||||
|
api.add_resource(Usage, '/v1.4/usage')
|
||||||
|
api.add_resource(EnergyDemand, '/v1.4/energy-demand')
|
||||||
|
# api.add_resource(LCA, '/v1.4/lca')
|
||||||
|
api.add_resource(MaterialLCACatalog, '/v1.4/material_lca_catalog/entries')
|
||||||
|
api.add_resource(MaterialLCACalculations, '/v1.4/material_lca_catalog/calculations')
|
||||||
|
api.add_resource(HeatPump, '/v1.4/heat-pump')
|
||||||
|
api.add_resource(User, '/v1.4/user')
|
||||||
|
api.add_resource(UserLogin, '/v1.4/user/login')
|
||||||
|
api.add_resource(SessionStart, '/v1.4/session/start')
|
||||||
|
api.add_resource(SessionEnd, '/v1.4/session/end')
|
||||||
|
api.add_resource(KeepSessionAlive, '/v1.4/session/keep_alive')
|
||||||
|
api.add_resource(CityInfo, '/v1.4/city_info')
|
||||||
|
api.add_resource(City, '/v1.4/city')
|
||||||
|
api.add_resource(Greenery, '/v1.4/greenery')
|
||||||
|
|
||||||
|
# Add api documentation
|
||||||
|
app.config.update({
|
||||||
|
'APISPEC_SPEC': APISpec(
|
||||||
|
title='Gamification Service',
|
||||||
|
version='v1.4',
|
||||||
|
plugins=[MarshmallowPlugin()],
|
||||||
|
openapi_version='2.0.0'
|
||||||
|
),
|
||||||
|
'APISPEC_SWAGGER_URL': '/swagger/', # URI to access API Doc JSON
|
||||||
|
'APISPEC_SWAGGER_UI_URL': '/api-docs/' # URI to access UI of API Doc
|
||||||
|
})
|
||||||
|
docs = FlaskApiSpec(app)
|
||||||
|
docs.register(HeatPump)
|
||||||
|
docs.register(User)
|
||||||
|
docs.register(UserLogin)
|
||||||
|
docs.register(City)
|
|
@ -2,18 +2,9 @@
|
||||||
Main
|
Main
|
||||||
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2021 Project Author name guillermo.gutierrezmorote@concordia.ca
|
Copyright © 2021 Project Author name guillermo.gutierrezmorote@concordia.ca
|
||||||
|
Project Collaborator name peteryefi@gmail.com
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import datetime
|
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
import flask
|
|
||||||
from apispec import APISpec
|
|
||||||
from apispec.ext.marshmallow import MarshmallowPlugin
|
|
||||||
from flask import Response
|
|
||||||
from flask_apispec.extension import FlaskApiSpec
|
|
||||||
from flask_restful import Api
|
|
||||||
|
|
||||||
from catalog_factories.construction_catalog_factory import ConstructionCatalogFactory
|
from catalog_factories.construction_catalog_factory import ConstructionCatalogFactory
|
||||||
from catalog_factories.greenery_catalog_factory import GreeneryCatalogFactory
|
from catalog_factories.greenery_catalog_factory import GreeneryCatalogFactory
|
||||||
from catalog_factories.usage_catalog_factory import UsageCatalogFactory
|
from catalog_factories.usage_catalog_factory import UsageCatalogFactory
|
||||||
|
@ -23,69 +14,11 @@ from imports.life_cycle_assessment_factory import LifeCycleAssessment
|
||||||
from imports.schedules_factory import SchedulesFactory
|
from imports.schedules_factory import SchedulesFactory
|
||||||
from imports.usage_factory import UsageFactory
|
from imports.usage_factory import UsageFactory
|
||||||
from imports.weather_factory import WeatherFactory
|
from imports.weather_factory import WeatherFactory
|
||||||
from hub_api.city_info import CityInfo
|
from flask import Response
|
||||||
from hub_api.geometry import Geometry
|
|
||||||
from hub_api.greenery_catalog import GreeneryCatalogEntries
|
|
||||||
from hub_api.greenery_catalog import GreeneryCatalogEntry
|
|
||||||
from hub_api.greenery_catalog import GreeneryCatalogNames
|
|
||||||
from hub_api.construction_catalog import ConstructionCatalogEntries
|
|
||||||
from hub_api.construction_catalog import ConstructionCatalogEntry
|
|
||||||
from hub_api.construction_catalog import ConstructionCatalogNames
|
|
||||||
from hub_api.usage_catalog import UsageCatalogEntries
|
|
||||||
from hub_api.usage_catalog import UsageCatalogEntry
|
|
||||||
from hub_api.usage_catalog import UsageCatalogNames
|
|
||||||
from hub_api.heat_pump import HeatPump
|
|
||||||
from hub_api.lca import MaterialLCACatalog
|
|
||||||
from hub_api.lca import MaterialLCACalculations
|
|
||||||
from hub_api.construction import Construction
|
|
||||||
from hub_api.usage import Usage
|
|
||||||
from hub_api.energy_demand import EnergyDemand
|
|
||||||
from hub_api.session import SessionStart, SessionEnd, KeepSessionAlive
|
|
||||||
from hub_api.uptime import Uptime
|
|
||||||
from hub_api.greenery import Greenery
|
|
||||||
import hub_api.helpers.session_helper as sh
|
import hub_api.helpers.session_helper as sh
|
||||||
|
import datetime
|
||||||
app = flask.Flask('gamification')
|
from pathlib import Path
|
||||||
api = Api(app)
|
from bootstrap import app
|
||||||
|
|
||||||
|
|
||||||
api.add_resource(Uptime, '/v1.3/uptime')
|
|
||||||
api.add_resource(Geometry, '/v1.3/geometry')
|
|
||||||
api.add_resource(GreeneryCatalogEntry, '/v1.3/greenery-catalog/entry')
|
|
||||||
api.add_resource(GreeneryCatalogEntries, '/v1.3/greenery-catalog/entries')
|
|
||||||
api.add_resource(GreeneryCatalogNames, '/v1.3/greenery-catalog/names')
|
|
||||||
api.add_resource(ConstructionCatalogEntry, '/v1.3/construction-catalog/entry')
|
|
||||||
api.add_resource(ConstructionCatalogEntries, '/v1.3/construction-catalog/entries')
|
|
||||||
api.add_resource(ConstructionCatalogNames, '/v1.3/construction-catalog/names')
|
|
||||||
api.add_resource(Construction, '/v1.3/construction')
|
|
||||||
api.add_resource(UsageCatalogEntry, '/v1.3/usage-catalog/entry')
|
|
||||||
api.add_resource(UsageCatalogEntries, '/v1.3/usage-catalog/entries')
|
|
||||||
api.add_resource(UsageCatalogNames, '/v1.3/usage-catalog/names')
|
|
||||||
api.add_resource(Usage, '/v1.3/usage')
|
|
||||||
api.add_resource(EnergyDemand, '/v1.3/energy-demand')
|
|
||||||
# api.add_resource(LCA, '/v1.3/lca')
|
|
||||||
api.add_resource(MaterialLCACatalog, '/v1.3/material_lca_catalog/entries')
|
|
||||||
api.add_resource(MaterialLCACalculations, '/v1.3/material_lca_catalog/calculations')
|
|
||||||
api.add_resource(HeatPump, '/v1.3/heat-pump')
|
|
||||||
api.add_resource(SessionStart, '/v1.3/session/start')
|
|
||||||
api.add_resource(SessionEnd, '/v1.3/session/end')
|
|
||||||
api.add_resource(KeepSessionAlive, '/v1.3/session/keep_alive')
|
|
||||||
api.add_resource(CityInfo, '/v1.3/city_info')
|
|
||||||
api.add_resource(Greenery, '/v1.3/greenery')
|
|
||||||
|
|
||||||
# Add api documentation
|
|
||||||
app.config.update({
|
|
||||||
'APISPEC_SPEC': APISpec(
|
|
||||||
title='Gamification Service',
|
|
||||||
version='v1.3',
|
|
||||||
plugins=[MarshmallowPlugin()],
|
|
||||||
openapi_version='2.0.0'
|
|
||||||
),
|
|
||||||
'APISPEC_SWAGGER_URL': '/swagger/', # URI to access API Doc JSON
|
|
||||||
'APISPEC_SWAGGER_UI_URL': '/swagger-ui/' # URI to access UI of API Doc
|
|
||||||
})
|
|
||||||
docs = FlaskApiSpec(app)
|
|
||||||
docs.register(HeatPump)
|
|
||||||
|
|
||||||
sh.begin_time = datetime.datetime.now()
|
sh.begin_time = datetime.datetime.now()
|
||||||
# initialize catalogs
|
# initialize catalogs
|
||||||
|
@ -93,13 +26,11 @@ sh.greenery_catalog = GreeneryCatalogFactory('nrel').catalog
|
||||||
sh.construction_catalog = ConstructionCatalogFactory('nrel').catalog
|
sh.construction_catalog = ConstructionCatalogFactory('nrel').catalog
|
||||||
sh.usage_catalog = UsageCatalogFactory('comnet').catalog
|
sh.usage_catalog = UsageCatalogFactory('comnet').catalog
|
||||||
|
|
||||||
|
|
||||||
# Enrich the city
|
# Enrich the city
|
||||||
data_path = (Path(__file__).parent / 'data').resolve()
|
data_path = (Path(__file__).parent / 'data').resolve()
|
||||||
rihno_path = (Path(data_path / 'dompark.3dm')).resolve()
|
rihno_path = (Path(data_path / 'dompark.3dm')).resolve()
|
||||||
city = GeometryFactory('rhino', rihno_path).city
|
city = GeometryFactory('rhino', rihno_path).city
|
||||||
|
|
||||||
|
|
||||||
for building in city.buildings:
|
for building in city.buildings:
|
||||||
# Rihno files have no information about the function or the year of construction
|
# Rihno files have no information about the function or the year of construction
|
||||||
building.year_of_construction = 1995
|
building.year_of_construction = 1995
|
||||||
|
@ -135,6 +66,7 @@ for building in city.buildings:
|
||||||
# Pass the city to the session helper to be used as default status.
|
# Pass the city to the session helper to be used as default status.
|
||||||
sh.city = city
|
sh.city = city
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def home():
|
def home():
|
||||||
return Response(headers={'Access-Control-Allow-Origin': '*'})
|
return Response(headers={'Access-Control-Allow-Origin': '*'})
|
||||||
|
|
|
@ -4,11 +4,24 @@ SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
Copyright © 2022 Project Author name guillermo.gutierrezmorote@concordia.ca
|
Copyright © 2022 Project Author name guillermo.gutierrezmorote@concordia.ca
|
||||||
"""
|
"""
|
||||||
import json
|
import json
|
||||||
|
from flask_apispec import use_kwargs, doc
|
||||||
from flask import Response, request
|
from flask import Response, request
|
||||||
from flask_restful import Resource
|
from flask_restful import Resource
|
||||||
|
|
||||||
from hub_api.helpers.session_helper import refresh_session
|
from hub_api.helpers.session_helper import refresh_session
|
||||||
|
from marshmallow import fields, Schema
|
||||||
|
from hub_api.helpers.auth import role_required
|
||||||
|
from persistence.models import UserRoles
|
||||||
|
from flask_apispec.views import MethodResource
|
||||||
|
from hub_logger import logger
|
||||||
|
|
||||||
|
|
||||||
|
class AuthorizationHeader(Schema):
|
||||||
|
Authorization = fields.Str(required=True, description='Authorization token')
|
||||||
|
AppID = fields.Str(required=True, description='ID of app accessing API')
|
||||||
|
|
||||||
|
|
||||||
|
class CitySchema(Schema):
|
||||||
|
city_file = fields.Raw(type='file', required=True, description='City file')
|
||||||
|
|
||||||
|
|
||||||
class CityInfo(Resource):
|
class CityInfo(Resource):
|
||||||
|
@ -70,3 +83,16 @@ class CityInfo(Resource):
|
||||||
'buildings': buildings
|
'buildings': buildings
|
||||||
}
|
}
|
||||||
return Response(json.dumps(response), headers=headers)
|
return Response(json.dumps(response), headers=headers)
|
||||||
|
|
||||||
|
|
||||||
|
class City(MethodResource, Resource):
|
||||||
|
@doc(description='Persist a city', tags=['PersistCity'])
|
||||||
|
@role_required(UserRoles.Admin.value)
|
||||||
|
@use_kwargs(AuthorizationHeader, location='headers')
|
||||||
|
@use_kwargs(CitySchema)
|
||||||
|
def post(self, **kwargs):
|
||||||
|
try:
|
||||||
|
return Response(response=json.dumps({'msg': 'Hello'}), status=201)
|
||||||
|
except Exception as err:
|
||||||
|
logger.error(err)
|
||||||
|
return Response(response=json.dumps({'err_msg': 'Sorry an error occurred while creating user'}), status=400)
|
||||||
|
|
73
hub_api/helpers/auth.py
Normal file
73
hub_api/helpers/auth.py
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
from datetime import datetime, timedelta, timezone
|
||||||
|
from typing import Dict
|
||||||
|
from jwt import JWT, jwk_from_pem
|
||||||
|
import os
|
||||||
|
from jwt.utils import get_int_from_datetime
|
||||||
|
from functools import wraps
|
||||||
|
from flask import request, g
|
||||||
|
from hub_logger import logger
|
||||||
|
from persistence.models import UserRoles
|
||||||
|
from jwt.exceptions import JWTException
|
||||||
|
|
||||||
|
instance = JWT()
|
||||||
|
|
||||||
|
|
||||||
|
def generate_auth_token(user: Dict):
|
||||||
|
private_key = "{}/rsa.pem".format(os.path.expanduser('~'))
|
||||||
|
with open(private_key, 'rb') as fh:
|
||||||
|
signing_key = jwk_from_pem(fh.read())
|
||||||
|
user['exp'] = get_int_from_datetime(datetime.now(timezone.utc) + timedelta(hours=24))
|
||||||
|
user['iat'] = get_int_from_datetime(datetime.now(timezone.utc))
|
||||||
|
return instance.encode(user, signing_key, alg='RS256')
|
||||||
|
|
||||||
|
|
||||||
|
def validate_auth_token(token: str):
|
||||||
|
public_key = "{}/rsa.pub".format(os.path.expanduser('~'))
|
||||||
|
with open(public_key, 'rb') as fh:
|
||||||
|
verifying_key = jwk_from_pem(fh.read())
|
||||||
|
return instance.decode(token, verifying_key, do_time_check=True)
|
||||||
|
|
||||||
|
|
||||||
|
def role_required(role: str):
|
||||||
|
def auth_module(user):
|
||||||
|
g.user = user
|
||||||
|
return user['role'] == role
|
||||||
|
|
||||||
|
"""
|
||||||
|
A wrapper to authorize specific roles for specific endpoints
|
||||||
|
:param roles: a list of roles allowed
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
def role_decorator(f):
|
||||||
|
@wraps(f)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
try:
|
||||||
|
token = request.headers['Authorization']
|
||||||
|
user = validate_auth_token(token)
|
||||||
|
|
||||||
|
if user is None:
|
||||||
|
return {'messages': 'You have not been authenticated'}, 401
|
||||||
|
allowed = auth_module(user['user'])
|
||||||
|
|
||||||
|
if user['user']['role'] == UserRoles.Admin.value and 'localhost' not in request.headers['Host']:
|
||||||
|
allowed = False
|
||||||
|
|
||||||
|
if not allowed:
|
||||||
|
return {'messages': 'You are not authorized'}, 403
|
||||||
|
return f(*args, **kwargs)
|
||||||
|
except KeyError as err:
|
||||||
|
# logger Error
|
||||||
|
logger.error(err)
|
||||||
|
return {'messages': 'Invalid payload'}, 400
|
||||||
|
except JWTException as err:
|
||||||
|
logger.error(err)
|
||||||
|
return {'messages': 'Invalid token'}, 401
|
||||||
|
except Exception as err:
|
||||||
|
logger.error(err)
|
||||||
|
return {'messages': 'Sorry, an error occurred while processing your request'}, 500
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
return role_decorator
|
||||||
|
|
113
hub_api/user.py
Normal file
113
hub_api/user.py
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
"""
|
||||||
|
HeatPump Service
|
||||||
|
SPDX - License - Identifier: LGPL - 3.0 - or -later
|
||||||
|
Copyright © 2022 Project Author Peter Yefi peteryefi@gmail.com
|
||||||
|
"""
|
||||||
|
import json
|
||||||
|
from flask import Response
|
||||||
|
from flask_apispec import use_kwargs, doc
|
||||||
|
from flask_apispec.views import MethodResource
|
||||||
|
from flask_restful import Resource
|
||||||
|
from marshmallow import Schema, fields
|
||||||
|
from imports.user_factory import UserFactory
|
||||||
|
from exports.user_factory import UserFactory as ExUserFactory
|
||||||
|
import os
|
||||||
|
from hub_logger import logger
|
||||||
|
from hub_api.helpers.auth import generate_auth_token, role_required
|
||||||
|
from persistence.models import UserRoles
|
||||||
|
|
||||||
|
|
||||||
|
class AuthorizationHeader(Schema):
|
||||||
|
Authorization = fields.Str(required=True, description='Authorization token')
|
||||||
|
AppID = fields.Str(required=True, description='ID of app accessing API')
|
||||||
|
|
||||||
|
|
||||||
|
class LoginPostSchema(Schema):
|
||||||
|
"""
|
||||||
|
Defines post data for users
|
||||||
|
"""
|
||||||
|
password = fields.String(required=True, description='Password of user')
|
||||||
|
email = fields.String(required=True, description='Email of user')
|
||||||
|
|
||||||
|
|
||||||
|
class UserPostSchema(LoginPostSchema):
|
||||||
|
"""
|
||||||
|
Defines post data for users
|
||||||
|
"""
|
||||||
|
name = fields.String(required=True, description='Name of user')
|
||||||
|
role = fields.String(required=True, description='Allowed user roles', enum=['Admin', 'Hub_Reader'])
|
||||||
|
|
||||||
|
|
||||||
|
class UserPutSchema(UserPostSchema):
|
||||||
|
"""
|
||||||
|
Defines put data for users
|
||||||
|
"""
|
||||||
|
id = fields.Int(required=True, description='The Id of the user to be Updated')
|
||||||
|
|
||||||
|
|
||||||
|
class User(MethodResource, Resource):
|
||||||
|
def __init__(self):
|
||||||
|
self.user_factory = UserFactory(db_name='hub_prod', app_env='PROD',
|
||||||
|
dotenv_path="{}/.env".format(os.path.expanduser('~')))
|
||||||
|
|
||||||
|
@doc(description='Create users', tags=['CreateUser'])
|
||||||
|
@role_required(UserRoles.Admin.value)
|
||||||
|
@use_kwargs(AuthorizationHeader, location='headers')
|
||||||
|
@use_kwargs(UserPostSchema)
|
||||||
|
def post(self, **kwargs):
|
||||||
|
try:
|
||||||
|
|
||||||
|
user = self.user_factory.create_user(name=kwargs["name"], email=kwargs["email"], password=kwargs["password"],
|
||||||
|
role=kwargs["role"])
|
||||||
|
if type(user) is dict:
|
||||||
|
return Response(response=json.dumps(user), status=400)
|
||||||
|
return Response(response=json.dumps({'user': {'id': user.id, 'name': user.name, 'email': user.email,
|
||||||
|
'password': user.password, 'role': user.role.value}}), status=201)
|
||||||
|
except Exception as err:
|
||||||
|
logger.error(err)
|
||||||
|
return Response(response=json.dumps({'err_msg': 'Sorry an error occurred while creating user'}), status=400)
|
||||||
|
|
||||||
|
@doc(description='Get all users', tags=['UpdateUsers'])
|
||||||
|
@use_kwargs(UserPutSchema)
|
||||||
|
@role_required(UserRoles.Admin.value)
|
||||||
|
@use_kwargs(AuthorizationHeader, location='headers')
|
||||||
|
def put(self, **kwargs):
|
||||||
|
try:
|
||||||
|
res = self.user_factory.update_user(user_id=kwargs['id'], name=kwargs['name'], password=kwargs['password'],
|
||||||
|
role=kwargs['role'], email=kwargs['email'])
|
||||||
|
if res:
|
||||||
|
return Response(response=json.dumps(res), status=400)
|
||||||
|
return Response(response=json.dumps({'success': 'user updated successfully'}), status=200)
|
||||||
|
except Exception as err:
|
||||||
|
logger.error(err)
|
||||||
|
return Response(response=json.dumps({'err_msg': 'Sorry, an error occurred while updating user'}),
|
||||||
|
status=400)
|
||||||
|
|
||||||
|
|
||||||
|
class UserLogin(MethodResource, Resource):
|
||||||
|
def __init__(self):
|
||||||
|
self.user_factory = ExUserFactory(db_name='hub_prod', app_env='PROD',
|
||||||
|
dotenv_path="{}/.env".format(os.path.expanduser('~')))
|
||||||
|
|
||||||
|
@doc(description='Create users', tags=['LoginUser'])
|
||||||
|
@use_kwargs(LoginPostSchema)
|
||||||
|
def post(self, **kwargs):
|
||||||
|
try:
|
||||||
|
user = self.user_factory.login_user(email=kwargs["email"], password=kwargs["password"])
|
||||||
|
if type(user) is dict:
|
||||||
|
return Response(response=json.dumps(user), status=400)
|
||||||
|
user = user[0]
|
||||||
|
user_dict = {
|
||||||
|
'user': {
|
||||||
|
'id': user.id,
|
||||||
|
'name': user.name,
|
||||||
|
'email': user.email,
|
||||||
|
'password': user.password,
|
||||||
|
'role': user.role.value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
user_dict['token'] = generate_auth_token(user_dict)
|
||||||
|
return Response(response=json.dumps(user_dict), status=201)
|
||||||
|
except Exception as err:
|
||||||
|
logger.error(err)
|
||||||
|
return Response(response=json.dumps({'err_msg': 'Sorry an error occurred while authenticating user'}), status=400)
|
|
@ -21,3 +21,4 @@ rhino3dm==7.7.0
|
||||||
scipy
|
scipy
|
||||||
PyYAML
|
PyYAML
|
||||||
pyecore==0.12.2
|
pyecore==0.12.2
|
||||||
|
jwt==1.3.1
|
Loading…
Reference in New Issue
Block a user