diff options
Diffstat (limited to 'opendc')
| -rw-r--r-- | opendc/api/v2/tiles/tileId/rack/machines/position/endpoint.py | 2 | ||||
| -rw-r--r-- | opendc/api/v2/users/endpoint.py | 6 | ||||
| -rw-r--r-- | opendc/api/v2/users/test_endpoint.py | 2 | ||||
| -rw-r--r-- | opendc/util/database.py | 126 | ||||
| -rw-r--r-- | opendc/util/rest.py | 49 |
5 files changed, 93 insertions, 92 deletions
diff --git a/opendc/api/v2/tiles/tileId/rack/machines/position/endpoint.py b/opendc/api/v2/tiles/tileId/rack/machines/position/endpoint.py index e769a049..72fd44d5 100644 --- a/opendc/api/v2/tiles/tileId/rack/machines/position/endpoint.py +++ b/opendc/api/v2/tiles/tileId/rack/machines/position/endpoint.py @@ -96,7 +96,7 @@ def PUT(request): return Response(409, 'Rack position occupied.') except Exception as e: - print e + print(e) return Response(400, 'Invalid Machine.') # Return this Machine diff --git a/opendc/api/v2/users/endpoint.py b/opendc/api/v2/users/endpoint.py index 2712c625..dca509ed 100644 --- a/opendc/api/v2/users/endpoint.py +++ b/opendc/api/v2/users/endpoint.py @@ -2,7 +2,7 @@ from werkzeug.exceptions import abort from opendc.models.user import User from opendc.util import exceptions -from opendc.util.database import fetch_one, insert +from opendc.util.database import DB from opendc.util.rest import Response @@ -14,7 +14,7 @@ def GET(request): except exceptions.ParameterError as e: return Response(400, str(e)) - user = fetch_one({'email': request.params_query['email']}, 'users') + user = DB.fetch_one({'email': request.params_query['email']}, 'users') if user is not None: return Response(404, f'User with email {request.params_query["email"]} not found') @@ -32,7 +32,7 @@ def POST(request): request.params_body['user']['googleId'] = request.google_id user = request.params_body['user'] - existing_user = fetch_one({'googleId': user['googleId']}, 'users') + existing_user = DB.fetch_one({'googleId': user['googleId']}, 'users') if existing_user is not None: return Response(409, '{} already exists.'.format(existing_user)) diff --git a/opendc/api/v2/users/test_endpoint.py b/opendc/api/v2/users/test_endpoint.py new file mode 100644 index 00000000..ffe2ce02 --- /dev/null +++ b/opendc/api/v2/users/test_endpoint.py @@ -0,0 +1,2 @@ +def test_get_user_missing_parameter(client): + print(client.get('/api/v2/users')) diff --git a/opendc/util/database.py b/opendc/util/database.py index 0e424aa4..24572279 100644 --- a/opendc/util/database.py +++ b/opendc/util/database.py @@ -7,91 +7,87 @@ from pymongo import MongoClient DATETIME_STRING_FORMAT = '%Y-%m-%dT%H:%M:%S' CONNECTION_POOL = None +DB = None -def init_connection_pool(user, password, database, host, port): - user = urllib.parse.quote_plus(user) # TODO: replace this with environment variable - password = urllib.parse.quote_plus(password) # TODO: same as above - database = urllib.parse.quote_plus(database) - host = urllib.parse.quote_plus(host) +class Database: + def __init__(self, user, password, database, host): + user = urllib.parse.quote_plus(user) # TODO: replace this with environment variable + password = urllib.parse.quote_plus(password) # TODO: same as above + database = urllib.parse.quote_plus(database) + host = urllib.parse.quote_plus(host) - global opendcdb + client = MongoClient('mongodb://%s:%s@%s/default_db?authSource=%s' % (user, password, host, database)) + self.opendc_db = client.opendc - client = MongoClient('mongodb://%s:%s@%s/default_db?authSource=%s' % (user, password, host, database)) - opendcdb = client.opendc + def fetch_one(self, query, collection): + """Uses existing mongo connection to return a single (the first) document in a collection matching the given + query as a JSON object. + The query needs to be in json format, i.e.: `{'name': prefab_name}`. + """ + bson = getattr(self.opendc_db, collection).find_one(query) -def fetch_one(query, collection): - """Uses existing mongo connection to return a single (the first) document in a collection matching the given - query as a JSON object. + return self.convert_bson_to_json(bson) - The query needs to be in json format, i.e.: `{'name': prefab_name}`. - """ - bson = getattr(opendcdb, collection).find_one(query) + def fetch_all(self, query, collection): + """Uses existing mongo connection to return all documents matching a given query, as a list of JSON objects. - return convert_bson_to_json(bson) + The query needs to be in json format, i.e.: `{'name': prefab_name}`. + """ + results = [] + cursor = getattr(self.opendc_db, collection).find(query) + for doc in cursor: + results.append(self.convert_bson_to_json(doc)) + return results + def insert(self, obj, collection): + """Updates an existing object.""" + bson = getattr(self.opendc_db, collection).insert(obj) -def fetch_all(query, collection): - """Uses existing mongo connection to return all documents matching a given query, as a list of JSON objects. + return self.convert_bson_to_json(bson) - The query needs to be in json format, i.e.: `{'name': prefab_name}`. - """ - results = [] - cursor = getattr(opendcdb, collection).find(query) - for doc in cursor: - results.append(convert_bson_to_json(doc)) - return results + def update(self, _id, obj, collection): + """Updates an existing object.""" + bson = getattr(self.opendc_db, collection).update({'_id': _id}, obj) + return self.convert_bson_to_json(bson) -def insert(obj, collection): - """Updates an existing object.""" - bson = getattr(opendcdb, collection).insert(obj) + def delete_one(self, query, collection): + """Deletes one object matching the given query. - return convert_bson_to_json(bson) + The query needs to be in json format, i.e.: `{'name': prefab_name}`. + """ + bson = getattr(self.opendc_db, collection).delete_one(query) + return self.convert_bson_to_json(bson) -def update(_id, obj, collection): - """Updates an existing object.""" - bson = getattr(opendcdb, collection).update({'_id': _id}, obj) + def delete_all(self, query, collection): + """Deletes all objects matching the given query. - return convert_bson_to_json(bson) + The query needs to be in json format, i.e.: `{'name': prefab_name}`. + """ + bson = getattr(self.opendc_db, collection).delete_many(query) + return self.convert_bson_to_json(bson) -def delete_one(query, collection): - """Deletes one object matching the given query. + @staticmethod + def convert_bson_to_json(bson): + """Converts a BSON representation to JSON and returns the JSON representation.""" + json_string = dumps(bson) + return json.loads(json_string) - The query needs to be in json format, i.e.: `{'name': prefab_name}`. - """ - bson = getattr(opendcdb, collection).delete_one(query) + @staticmethod + def datetime_to_string(datetime_to_convert): + """Return a database-compatible string representation of the given datetime object.""" + return datetime_to_convert.strftime(DATETIME_STRING_FORMAT) - return convert_bson_to_json(bson) + @staticmethod + def string_to_datetime(string_to_convert): + """Return a datetime corresponding to the given string representation.""" + return datetime.strptime(string_to_convert, DATETIME_STRING_FORMAT) -def delete_all(query, collection): - """Deletes all objects matching the given query. - - The query needs to be in json format, i.e.: `{'name': prefab_name}`. - """ - bson = getattr(opendcdb, collection).delete_many(query) - - return convert_bson_to_json(bson) - - -def convert_bson_to_json(bson): - # Convert BSON representation to JSON - json_string = dumps(bson) - # Load as a JSON object - return json.loads(json_string) - - -def datetime_to_string(datetime_to_convert): - """Return a database-compatible string representation of the given datetime object.""" - - return datetime_to_convert.strftime(DATETIME_STRING_FORMAT) - - -def string_to_datetime(string_to_convert): - """Return a datetime corresponding to the given string representation.""" - - return datetime.strptime(string_to_convert, DATETIME_STRING_FORMAT) +def initialize_database(user, password, database, host): + global DB + DB = Database(user, password, database, host) diff --git a/opendc/util/rest.py b/opendc/util/rest.py index d892a358..2312b199 100644 --- a/opendc/util/rest.py +++ b/opendc/util/rest.py @@ -1,14 +1,12 @@ import importlib import json +import os import sys from oauth2client import client, crypt from opendc.util import exceptions, parameter_checker -with open(sys.argv[1]) as f: - KEYS = json.load(f) - class Request(object): """WebSocket message to REST request mapping.""" @@ -45,6 +43,7 @@ class Request(object): module_base = 'opendc.api.{}.endpoint' module_path = self.path.replace('/', '.') + print(module_base.format(module_path)) self.module = importlib.import_module(module_base.format(module_path)) except ImportError: raise exceptions.UnimplementedEndpointError('Unimplemented endpoint: {}.'.format(self.path)) @@ -60,31 +59,14 @@ class Request(object): # Verify the user + if "OPENDC_FLASK_TESTING" in os.environ: + return + try: self.google_id = self._verify_token(self.token) - except crypt.AppIdentityError as e: raise exceptions.AuthorizationTokenError(e) - def _verify_token(self, token): - """Return the ID of the signed-in user. - - Or throw an Exception if the token is invalid. - """ - - try: - idinfo = client.verify_id_token(token, KEYS['OAUTH_CLIENT_ID']) - except Exception as e: - raise crypt.AppIdentityError('Exception caught trying to verify ID token: {}'.format(e)) - - if idinfo['aud'] != KEYS['OAUTH_CLIENT_ID']: - raise crypt.AppIdentityError('Unrecognized client.') - - if idinfo['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: - raise crypt.AppIdentityError('Wrong issuer.') - - return idinfo['sub'] - def check_required_parameters(self, **kwargs): """Raise an error if a parameter is missing or of the wrong type.""" @@ -108,6 +90,27 @@ class Request(object): return json.dumps(self.message) + @staticmethod + def _verify_token(token): + """Return the ID of the signed-in user. + + Or throw an Exception if the token is invalid. + """ + + try: + id_info = client.verify_id_token(token, os.environ['OPENDC_OAUTH_CLIENT_ID']) + except Exception as e: + print(e) + raise crypt.AppIdentityError('Exception caught trying to verify ID token: {}'.format(e)) + + if id_info['aud'] != os.environ['OPENDC_OAUTH_CLIENT_ID']: + raise crypt.AppIdentityError('Unrecognized client.') + + if id_info['iss'] not in ['accounts.google.com', 'https://accounts.google.com']: + raise crypt.AppIdentityError('Wrong issuer.') + + return id_info['sub'] + class Response(object): """Response to websocket mapping""" |
