From 8e3d6c5a829bf63157b2b6e96fece8a9762e8498 Mon Sep 17 00:00:00 2001 From: Aadi Desai <21363892+supleed2@users.noreply.github.com> Date: Wed, 2 Feb 2022 11:17:10 +0000 Subject: [PATCH 01/17] Initial commit --- .gitignore | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b6e4761 --- /dev/null +++ b/.gitignore @@ -0,0 +1,129 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ From 1524348974b096045700301d087eac397bdd1c64 Mon Sep 17 00:00:00 2001 From: Benjamin Ramhorst Date: Wed, 2 Feb 2022 22:52:07 +0000 Subject: [PATCH 02/17] Created basic project --- .idea/.gitignore | 8 +++++++ .idea/ELEC60013-ES-CW1-Server.iml | 21 +++++++++++++++++++ .../inspectionProfiles/profiles_settings.xml | 6 ++++++ .idea/misc.xml | 4 ++++ .idea/modules.xml | 8 +++++++ .idea/vcs.xml | 6 ++++++ app.py | 11 ++++++++++ 7 files changed, 64 insertions(+) create mode 100644 .idea/.gitignore create mode 100644 .idea/ELEC60013-ES-CW1-Server.iml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 app.py diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/ELEC60013-ES-CW1-Server.iml b/.idea/ELEC60013-ES-CW1-Server.iml new file mode 100644 index 0000000..02d2170 --- /dev/null +++ b/.idea/ELEC60013-ES-CW1-Server.iml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..74962bf --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2164f7b --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..c216b4e --- /dev/null +++ b/app.py @@ -0,0 +1,11 @@ +from flask import Flask + +app = Flask(__name__) + +@app.route('/') +def hello_world(): # put application's code here + return 'Hello World!' + + +if __name__ == '__main__': + app.run() From 09b55f9275213f16ab1931ba818f2e36dadaff83 Mon Sep 17 00:00:00 2001 From: Benjamin Ramhorst Date: Wed, 2 Feb 2022 22:58:59 +0000 Subject: [PATCH 03/17] Modified .gitignore to ignore Firebase keys --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index b6e4761..6640694 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Firebase key +firebase-key.json + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] From e4bfb40c1ac038c6cc4204539a122747b47ae865 Mon Sep 17 00:00:00 2001 From: Benjamin Ramhorst Date: Wed, 2 Feb 2022 23:06:27 +0000 Subject: [PATCH 04/17] Added Firebase to project --- app.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app.py b/app.py index c216b4e..882bad7 100644 --- a/app.py +++ b/app.py @@ -1,11 +1,15 @@ from flask import Flask +import firebase_admin +from firebase_admin import credentials +from firebase_admin import firestore + app = Flask(__name__) @app.route('/') def hello_world(): # put application's code here - return 'Hello World!' - + return 'Hello World! I am the dog you tracked with the amazing sensor from LEG industries...kidding this is just the home page :)' if __name__ == '__main__': + firebase_admin.initialize_app(credentials.Certificate('firebase-key.json')) app.run() From 4585af038758573e7bf43a4d18cf18087a24ff98 Mon Sep 17 00:00:00 2001 From: Benjamin Ramhorst Date: Wed, 2 Feb 2022 23:19:39 +0000 Subject: [PATCH 05/17] Added examples of reading and writing to the database --- app.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/app.py b/app.py index 882bad7..abc57ef 100644 --- a/app.py +++ b/app.py @@ -5,11 +5,37 @@ from firebase_admin import credentials from firebase_admin import firestore app = Flask(__name__) +firebase = firebase_admin.initialize_app(credentials.Certificate('firebase-key.json')) @app.route('/') def hello_world(): # put application's code here return 'Hello World! I am the dog you tracked with the amazing sensor from LEG industries...kidding this is just the home page :)' +# An example of reading data from Firebase +# Taken from Firebase documentation +@app.route('/example/read', methods=['GET']) +def exampleRead(): + doc_ref = firestore.client().collection(u'cities').document(u'LA') + doc = doc_ref.get() + if doc.exists: + return f'Document data: {doc.to_dict()}' + else: + return u'No such document!' + +# An example of saving data to Firebase +# Taken from Firebase documentation +# This should be a POST method...will change later +@app.route('/example/write', methods=['GET']) +def examnpleWrite(): + data = { + u'name': u'Los Angeles', + u'state': u'CA', + u'country': u'USA' + } + + # Add a new doc in collection 'cities' with ID 'LA' + firestore.client().collection(u'cities').document(u'LA').set(data) + return 'Saved to Firebase' + if __name__ == '__main__': - firebase_admin.initialize_app(credentials.Certificate('firebase-key.json')) app.run() From 57dba312abf77c60bf09725f22970e12a8da7da6 Mon Sep 17 00:00:00 2001 From: Benjamin Ramhorst <59868635+bo3z@users.noreply.github.com> Date: Fri, 4 Feb 2022 13:15:23 +0000 Subject: [PATCH 06/17] Added basic registration - not fully tested. Includes user verification, linking to device. --- app.py | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 61 insertions(+), 6 deletions(-) diff --git a/app.py b/app.py index abc57ef..b70d246 100644 --- a/app.py +++ b/app.py @@ -1,16 +1,71 @@ -from flask import Flask - -import firebase_admin -from firebase_admin import credentials -from firebase_admin import firestore +import json +from random import randint +from flask import Flask, request +from flask_mail import Mail +from firebase_admin import credentials, firestore, auth +# Initialize Flask app app = Flask(__name__) + +# Initalize Mail instance +app.config['MAIL_SERVER']='smtp.gmail.com' +app.config['MAIL_PORT'] = 465 +#app.config['MAIL_USERNAME'] = '' +#app.config['MAIL_PASSWORD'] = '' +app.config['MAIL_USE_TLS'] = False +app.config['MAIL_USE_SSL'] = True +mail = Mail(app) + +# Initialize Firebase firebase = firebase_admin.initialize_app(credentials.Certificate('firebase-key.json')) + @app.route('/') -def hello_world(): # put application's code here +def hello_world(): return 'Hello World! I am the dog you tracked with the amazing sensor from LEG industries...kidding this is just the home page :)' +@app.route('/auth/register', methods=['POST']): +def register(): + email = request.form.get('email') + password = request.form.get('email') + name = request.form.get('name') + deviceId = request.form.get('deviceid') + + # Some fields are not present + if email is None or password is None or name is None or deviceId is None: + return Response("{'error':'Entires missing'}", status=400, mimetype='application/json') + + # Register user with Firebase authentication + user = auth.create_user( + email=email + email_verified=False, + password=password, + display_name=name, + disabled=False) + + # Prompt the user to verify their email + code = randint(100000, 999999) + data = { + u'code': code + } + firestore.client().collection(u'verification').document(user.uid).set(code) + msg = Message('Please verify your email for BarkFinder', sender = 'TBA', recipients = [email]) + msg.body = '''Hey {}! Thank you for signing up for BarkFinder. + In order to use our sevices, could you please verify your email address by logging in and entering this code {}''' + .format(name, code) + mail.send(msg) + + # Link the user to the device + data = { + u'devices': [deviceId] + } + firestore.client().collection(u'devices').document(user.uid).set(data) + + # User succesfully created and linked to device + resp = {"uid":user.uid} + return Response(json.dumps(resp, 2), status=201, mimetype='application/json') + + # An example of reading data from Firebase # Taken from Firebase documentation @app.route('/example/read', methods=['GET']) From 7e234da82a7f82359b5f6bea585edc2cb0e6e02a Mon Sep 17 00:00:00 2001 From: Benjamin Ramhorst Date: Sun, 6 Feb 2022 11:45:29 +0000 Subject: [PATCH 07/17] Registration bug fixes --- app.py | 56 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/app.py b/app.py index b70d246..3f218bb 100644 --- a/app.py +++ b/app.py @@ -1,8 +1,10 @@ import json -from random import randint -from flask import Flask, request -from flask_mail import Mail +from random import randint +import firebase_admin +from flask import Flask, Response, request +from flask_mail import Mail, Message from firebase_admin import credentials, firestore, auth +from firebase_admin._auth_utils import EmailAlreadyExistsError # Initialize Flask app app = Flask(__name__) @@ -10,8 +12,8 @@ app = Flask(__name__) # Initalize Mail instance app.config['MAIL_SERVER']='smtp.gmail.com' app.config['MAIL_PORT'] = 465 -#app.config['MAIL_USERNAME'] = '' -#app.config['MAIL_PASSWORD'] = '' +app.config['MAIL_USERNAME'] = 'legbarkr@gmail.com' +app.config['MAIL_PASSWORD'] = '!Password123' app.config['MAIL_USE_TLS'] = False app.config['MAIL_USE_SSL'] = True mail = Mail(app) @@ -19,40 +21,46 @@ mail = Mail(app) # Initialize Firebase firebase = firebase_admin.initialize_app(credentials.Certificate('firebase-key.json')) - @app.route('/') def hello_world(): return 'Hello World! I am the dog you tracked with the amazing sensor from LEG industries...kidding this is just the home page :)' -@app.route('/auth/register', methods=['POST']): +@app.route('/auth/register', methods=['POST']) def register(): - email = request.form.get('email') - password = request.form.get('email') - name = request.form.get('name') - deviceId = request.form.get('deviceid') + body = request.json + + if body is None: + return Response("{'error':'Invalid request - please provide a body'}", status=400, mimetype='application/json') + + email = body['email'] + password = body['password'] + name = body['name'] + deviceId = body['deviceid'] # Some fields are not present if email is None or password is None or name is None or deviceId is None: - return Response("{'error':'Entires missing'}", status=400, mimetype='application/json') + return Response("{'error':'Entries missing'}", status=400, mimetype='application/json') # Register user with Firebase authentication - user = auth.create_user( - email=email - email_verified=False, - password=password, - display_name=name, - disabled=False) + try: + user = auth.create_user( + email=email, + email_verified=False, + password=password, + display_name=name, + disabled=False) + except EmailAlreadyExistsError: + return Response("{'error':'User with given email address already exists'}", status=409, mimetype='application/json') # Prompt the user to verify their email code = randint(100000, 999999) data = { u'code': code } - firestore.client().collection(u'verification').document(user.uid).set(code) + firestore.client().collection(u'verification').document(user.uid).set(data) msg = Message('Please verify your email for BarkFinder', sender = 'TBA', recipients = [email]) - msg.body = '''Hey {}! Thank you for signing up for BarkFinder. - In order to use our sevices, could you please verify your email address by logging in and entering this code {}''' - .format(name, code) + msg.body = '''Hey {}! Thank you for signing up for BarkFinder. + In order to use our sevices, could you please verify your email address by logging in and entering this code {}'''.format(name, code) mail.send(msg) # Link the user to the device @@ -61,9 +69,9 @@ def register(): } firestore.client().collection(u'devices').document(user.uid).set(data) - # User succesfully created and linked to device + # User successfully created and linked to device resp = {"uid":user.uid} - return Response(json.dumps(resp, 2), status=201, mimetype='application/json') + return Response(json.dumps(resp), status=201, mimetype='application/json') # An example of reading data from Firebase From d54ee5e6b28b35d4b5c24a95f28c7ae8e2111eff Mon Sep 17 00:00:00 2001 From: Benjamin Ramhorst Date: Sun, 6 Feb 2022 14:18:22 +0000 Subject: [PATCH 08/17] Major code refractor, allows easier integration later --- api/authentication.py | 58 ++++++++++++++++++++++ api/data.py | 0 app.py | 110 ++++++------------------------------------ config/variables.py | 9 ++++ lib/mail.py | 8 +++ 5 files changed, 89 insertions(+), 96 deletions(-) create mode 100644 api/authentication.py create mode 100644 api/data.py create mode 100644 config/variables.py create mode 100644 lib/mail.py diff --git a/api/authentication.py b/api/authentication.py new file mode 100644 index 0000000..613ed59 --- /dev/null +++ b/api/authentication.py @@ -0,0 +1,58 @@ +import json +import lib.mail +from random import randint +from flask import Response, Blueprint, request +from firebase_admin import firestore, auth +from firebase_admin._auth_utils import EmailAlreadyExistsError + +authentication = Blueprint('authentication', __name__) + +@authentication.route('/authentication/register', methods=['POST']) +def register(): + body = request.json + if body is None: + return Response("{'error':'Invalid request - please provide a body'}", status=400, mimetype='application/json') + + email = body['email'] + password = body['password'] + name = body['name'] + deviceId = body['deviceid'] + + # Some fields are not present + if email is None or password is None or name is None or deviceId is None: + return Response("{'error':'Entries missing'}", status=400, mimetype='application/json') + + # Register user with Firebase authentication + try: + user = auth.create_user( + email=email, + email_verified=False, + password=password, + display_name=name, + disabled=False) + except EmailAlreadyExistsError: + return Response("{'error':'User with given email address already exists'}", status=409, mimetype='application/json') + + # Prompt the user to verify their email + code = randint(100000, 999999) + data = { + u'code': code + } + firestore.client().collection(u'verification').document(user.uid).set(data) + + subject = 'Please verify your email for BarkFinder' + sender = 'legbarkr@gmail.com' + recipients = [email] + body = '''Hey {}! Thank you for signing up for BarkFinder. + In order to use our sevices, could you please verify your email address by logging in and entering this code {}'''.format(name, code) + lib.mail.send(subject, sender, recipients, body) + + # Link the user to the device + data = { + u'devices': [deviceId] + } + firestore.client().collection(u'devices').document(user.uid).set(data) + + # User successfully created and linked to device, return 201 + resp = {"uid": user.uid} + return Response(json.dumps(resp), status=201, mimetype='application/json') \ No newline at end of file diff --git a/api/data.py b/api/data.py new file mode 100644 index 0000000..e69de29 diff --git a/app.py b/app.py index 3f218bb..3196e5e 100644 --- a/app.py +++ b/app.py @@ -1,104 +1,22 @@ -import json -from random import randint -import firebase_admin -from flask import Flask, Response, request -from flask_mail import Mail, Message -from firebase_admin import credentials, firestore, auth -from firebase_admin._auth_utils import EmailAlreadyExistsError +from config.variables import MAIL_SERVER, MAIL_PORT, MAIL_USERNAME, MAIL_PASSWORD, MAIL_USE_SSL, MAIL_USE_TLS +from flask import Flask +from firebase_admin import credentials, initialize_app +from api.authentication import authentication -# Initialize Flask app +# Initialize Flask app and register all the endpoints app = Flask(__name__) +app.register_blueprint(authentication) -# Initalize Mail instance -app.config['MAIL_SERVER']='smtp.gmail.com' -app.config['MAIL_PORT'] = 465 -app.config['MAIL_USERNAME'] = 'legbarkr@gmail.com' -app.config['MAIL_PASSWORD'] = '!Password123' -app.config['MAIL_USE_TLS'] = False -app.config['MAIL_USE_SSL'] = True -mail = Mail(app) +# Initialize Mail instance +app.config['MAIL_SERVER'] = MAIL_SERVER +app.config['MAIL_PORT'] = MAIL_PORT +app.config['MAIL_USERNAME'] = MAIL_USERNAME +app.config['MAIL_PASSWORD'] = MAIL_PASSWORD +app.config['MAIL_USE_TLS'] = MAIL_USE_TLS +app.config['MAIL_USE_SSL'] = MAIL_USE_SSL # Initialize Firebase -firebase = firebase_admin.initialize_app(credentials.Certificate('firebase-key.json')) - -@app.route('/') -def hello_world(): - return 'Hello World! I am the dog you tracked with the amazing sensor from LEG industries...kidding this is just the home page :)' - -@app.route('/auth/register', methods=['POST']) -def register(): - body = request.json - - if body is None: - return Response("{'error':'Invalid request - please provide a body'}", status=400, mimetype='application/json') - - email = body['email'] - password = body['password'] - name = body['name'] - deviceId = body['deviceid'] - - # Some fields are not present - if email is None or password is None or name is None or deviceId is None: - return Response("{'error':'Entries missing'}", status=400, mimetype='application/json') - - # Register user with Firebase authentication - try: - user = auth.create_user( - email=email, - email_verified=False, - password=password, - display_name=name, - disabled=False) - except EmailAlreadyExistsError: - return Response("{'error':'User with given email address already exists'}", status=409, mimetype='application/json') - - # Prompt the user to verify their email - code = randint(100000, 999999) - data = { - u'code': code - } - firestore.client().collection(u'verification').document(user.uid).set(data) - msg = Message('Please verify your email for BarkFinder', sender = 'TBA', recipients = [email]) - msg.body = '''Hey {}! Thank you for signing up for BarkFinder. - In order to use our sevices, could you please verify your email address by logging in and entering this code {}'''.format(name, code) - mail.send(msg) - - # Link the user to the device - data = { - u'devices': [deviceId] - } - firestore.client().collection(u'devices').document(user.uid).set(data) - - # User successfully created and linked to device - resp = {"uid":user.uid} - return Response(json.dumps(resp), status=201, mimetype='application/json') - - -# An example of reading data from Firebase -# Taken from Firebase documentation -@app.route('/example/read', methods=['GET']) -def exampleRead(): - doc_ref = firestore.client().collection(u'cities').document(u'LA') - doc = doc_ref.get() - if doc.exists: - return f'Document data: {doc.to_dict()}' - else: - return u'No such document!' - -# An example of saving data to Firebase -# Taken from Firebase documentation -# This should be a POST method...will change later -@app.route('/example/write', methods=['GET']) -def examnpleWrite(): - data = { - u'name': u'Los Angeles', - u'state': u'CA', - u'country': u'USA' - } - - # Add a new doc in collection 'cities' with ID 'LA' - firestore.client().collection(u'cities').document(u'LA').set(data) - return 'Saved to Firebase' +firebase = initialize_app(credentials.Certificate('firebase-key.json')) if __name__ == '__main__': app.run() diff --git a/config/variables.py b/config/variables.py new file mode 100644 index 0000000..bf63e55 --- /dev/null +++ b/config/variables.py @@ -0,0 +1,9 @@ +# App config file with various variables and settings + +# Email config +MAIL_SERVER = 'smtp.gmail.com' +MAIL_PORT = 465 +MAIL_USERNAME = 'legbarkr@gmail.com' +MAIL_PASSWORD = '!Password123' +MAIL_USE_TLS = False +MAIL_USE_SSL = True \ No newline at end of file diff --git a/lib/mail.py b/lib/mail.py new file mode 100644 index 0000000..b6781c7 --- /dev/null +++ b/lib/mail.py @@ -0,0 +1,8 @@ +from flask import current_app +from flask_mail import Mail, Message + +def send(subject, sender, recipients, body): + mail = Mail(current_app) + msg = Message(subject, sender=sender, recipients=recipients) + msg.body = body + mail.send(msg) \ No newline at end of file From 8b1ce01079019d7c5f1ecbdf7d1da52698707d0a Mon Sep 17 00:00:00 2001 From: Benjamin Ramhorst Date: Mon, 7 Feb 2022 13:10:58 +0000 Subject: [PATCH 09/17] Added verification endpoint --- .gcloudignore | 19 +++++++++++++++++++ api/authentication.py | 44 ++++++++++++++++++++++++++++--------------- app.yaml | 1 + lib/utils.py | 26 +++++++++++++++++++++++++ app.py => main.py | 4 ++++ requirements.txt | 3 +++ 6 files changed, 82 insertions(+), 15 deletions(-) create mode 100644 .gcloudignore create mode 100644 app.yaml create mode 100644 lib/utils.py rename app.py => main.py (93%) create mode 100644 requirements.txt diff --git a/.gcloudignore b/.gcloudignore new file mode 100644 index 0000000..603f0b6 --- /dev/null +++ b/.gcloudignore @@ -0,0 +1,19 @@ +# This file specifies files that are *not* uploaded to Google Cloud +# using gcloud. It follows the same syntax as .gitignore, with the addition of +# "#!include" directives (which insert the entries of the given .gitignore-style +# file at that point). +# +# For more information, run: +# $ gcloud topic gcloudignore +# +.gcloudignore +# If you would like to upload your .git directory, .gitignore file or files +# from your .gitignore file, remove the corresponding line +# below: +.git +.gitignore + +# Python pycache: +__pycache__/ +# Ignored by the build system +/setup.cfg \ No newline at end of file diff --git a/api/authentication.py b/api/authentication.py index 613ed59..8c56b95 100644 --- a/api/authentication.py +++ b/api/authentication.py @@ -1,5 +1,5 @@ import json -import lib.mail +import lib.utils from random import randint from flask import Response, Blueprint, request from firebase_admin import firestore, auth @@ -33,19 +33,9 @@ def register(): except EmailAlreadyExistsError: return Response("{'error':'User with given email address already exists'}", status=409, mimetype='application/json') - # Prompt the user to verify their email - code = randint(100000, 999999) - data = { - u'code': code - } - firestore.client().collection(u'verification').document(user.uid).set(data) - - subject = 'Please verify your email for BarkFinder' - sender = 'legbarkr@gmail.com' - recipients = [email] - body = '''Hey {}! Thank you for signing up for BarkFinder. - In order to use our sevices, could you please verify your email address by logging in and entering this code {}'''.format(name, code) - lib.mail.send(subject, sender, recipients, body) + # Prompt the user to get verified + code = lib.utils.saveVerificationCode(user.uid) + lib.utils.sendVerificationMail(name, email, code) # Link the user to the device data = { @@ -55,4 +45,28 @@ def register(): # User successfully created and linked to device, return 201 resp = {"uid": user.uid} - return Response(json.dumps(resp), status=201, mimetype='application/json') \ No newline at end of file + return Response(json.dumps(resp), status=201, mimetype='application/json') + +@authentication.route('/authentication/verify', methods=['POST']) +def verify(): + body = request.json + if body is None: + return Response("{'error':'Invalid request - please provide a body'}", status=400, mimetype='application/json') + + uid = body['uid'] + code = body['code'] + + doc = firestore.client().collection(u'verification').document(uid).get() + if doc.exists: + if doc.to_dict()['code'] == code: + auth.update_user(uid, email_verified=True) + firestore.client().collection(u'verification').document(uid).delete() + return Response("{'error':'User verified'}", status=200, mimetype='application/json') + else: + return Response("{'error':'Invalid code'}", status=400, mimetype='application/json') + else: + user = auth.get_user(uid) + code = lib.utils.saveVerificationCode(user.uid) + lib.utils.sendVerificationMail(user.display_name, user.email, code) + return Response("{'error':'Server couldn't find code, creating new one and sending email'}", status=500, mimetype='application/json') + diff --git a/app.yaml b/app.yaml new file mode 100644 index 0000000..a0b5f22 --- /dev/null +++ b/app.yaml @@ -0,0 +1 @@ +runtime: python38 \ No newline at end of file diff --git a/lib/utils.py b/lib/utils.py new file mode 100644 index 0000000..2488e41 --- /dev/null +++ b/lib/utils.py @@ -0,0 +1,26 @@ +from random import randint +from flask import current_app +from flask_mail import Mail, Message +from firebase_admin import firestore + +def sendMail(subject, sender, recipients, body): + mail = Mail(current_app) + msg = Message(subject, sender=sender, recipients=recipients) + msg.body = body + mail.send(msg) + +def saveVerificationCode(uid): + code = randint(100000, 999999) + data = { + u'code': code + } + firestore.client().collection(u'verification').document(uid).set(data) + return code + +def sendVerificationMail(name, email, code): + subject = 'Please verify your email for BarkFinder' + sender = 'legbarkr@gmail.com' + recipients = [email] + body = '''Hey {}! Thank you for signing up for BarkFinder. + In order to use our sevices, could you please verify your email address by logging in and entering this code {}'''.format(name, code) + sendMail(subject, sender, recipients, body) diff --git a/app.py b/main.py similarity index 93% rename from app.py rename to main.py index 3196e5e..e12d427 100644 --- a/app.py +++ b/main.py @@ -18,5 +18,9 @@ app.config['MAIL_USE_SSL'] = MAIL_USE_SSL # Initialize Firebase firebase = initialize_app(credentials.Certificate('firebase-key.json')) +@app.route('/') +def hello(): + return 'Hello World' + if __name__ == '__main__': app.run() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..9af04b9 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +flask +flask_mail +firebase_admin \ No newline at end of file From c470ebf42ddab65b3604d38a9a637ba9368bac34 Mon Sep 17 00:00:00 2001 From: Benjamin Ramhorst Date: Mon, 7 Feb 2022 13:15:57 +0000 Subject: [PATCH 10/17] Added placeholder functions to check if user is logged in --- api/authentication.py | 1 - lib/mail.py | 8 -------- lib/utils.py | 9 ++++++++- 3 files changed, 8 insertions(+), 10 deletions(-) delete mode 100644 lib/mail.py diff --git a/api/authentication.py b/api/authentication.py index 8c56b95..1da55cb 100644 --- a/api/authentication.py +++ b/api/authentication.py @@ -1,6 +1,5 @@ import json import lib.utils -from random import randint from flask import Response, Blueprint, request from firebase_admin import firestore, auth from firebase_admin._auth_utils import EmailAlreadyExistsError diff --git a/lib/mail.py b/lib/mail.py deleted file mode 100644 index b6781c7..0000000 --- a/lib/mail.py +++ /dev/null @@ -1,8 +0,0 @@ -from flask import current_app -from flask_mail import Mail, Message - -def send(subject, sender, recipients, body): - mail = Mail(current_app) - msg = Message(subject, sender=sender, recipients=recipients) - msg.body = body - mail.send(msg) \ No newline at end of file diff --git a/lib/utils.py b/lib/utils.py index 2488e41..ba7fbbf 100644 --- a/lib/utils.py +++ b/lib/utils.py @@ -1,7 +1,7 @@ from random import randint from flask import current_app from flask_mail import Mail, Message -from firebase_admin import firestore +from firebase_admin import auth, firestore def sendMail(subject, sender, recipients, body): mail = Mail(current_app) @@ -24,3 +24,10 @@ def sendVerificationMail(name, email, code): body = '''Hey {}! Thank you for signing up for BarkFinder. In order to use our sevices, could you please verify your email address by logging in and entering this code {}'''.format(name, code) sendMail(subject, sender, recipients, body) + +def userLoggedInAndVerfied(token): + # Need frontend to test this + # decoded_token = auth.verify_id_token(token) + # uid = decoded_token['uid'] + # isVerified = auth.get_user(uid).email_verified + return True #placeholder \ No newline at end of file From e0f2f18bd23494be0148fa37d6805c9fcee90704 Mon Sep 17 00:00:00 2001 From: Benjamin Ramhorst Date: Mon, 7 Feb 2022 13:45:10 +0000 Subject: [PATCH 11/17] Added endpoints for saving measurements --- api/data.py | 28 ++++++++++++++++++++++++++++ main.py | 3 +++ 2 files changed, 31 insertions(+) diff --git a/api/data.py b/api/data.py index e69de29..978c993 100644 --- a/api/data.py +++ b/api/data.py @@ -0,0 +1,28 @@ +import datetime +from flask import Response, Blueprint, request +from firebase_admin import firestore + +data = Blueprint('data', __name__) + +@data.route('/readings/save', methods=['POST']) +def uploadReadings(): + deviceId = request.headers.get('deviceid') + if deviceId is None: + return Response("{'error':'Device not specified'}", status=400, mimetype='application/json') + + body = request.json + if body is None: + return Response("{'error':'Invalid request - please provide a body'}", status=400, mimetype='application/json') + body['timestamp'] = datetime.datetime.now() + + doc = firestore.client().collection(u'readings').document(deviceId).get() + if doc.exists: + list = doc.to_dict()['data'] + list.append(body) + data = list + else: + data = [body] + + upload = {'data': data} + firestore.client().collection(u'readings').document(deviceId).set(upload) + return Response("{'success':'Data saved'}", status=200, mimetype='application/json') diff --git a/main.py b/main.py index e12d427..fc5d5fb 100644 --- a/main.py +++ b/main.py @@ -2,10 +2,13 @@ from config.variables import MAIL_SERVER, MAIL_PORT, MAIL_USERNAME, MAIL_PASSWOR from flask import Flask from firebase_admin import credentials, initialize_app from api.authentication import authentication +from api.data import data # Initialize Flask app and register all the endpoints app = Flask(__name__) app.register_blueprint(authentication) +app.register_blueprint(data) + # Initialize Mail instance app.config['MAIL_SERVER'] = MAIL_SERVER From 2fa0e252f8c19129d06313d24198aa0c47537a41 Mon Sep 17 00:00:00 2001 From: Benjamin Ramhorst Date: Mon, 7 Feb 2022 13:54:40 +0000 Subject: [PATCH 12/17] Added endpoints for retrieving device data --- api/data.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/api/data.py b/api/data.py index 978c993..879f5ef 100644 --- a/api/data.py +++ b/api/data.py @@ -1,7 +1,9 @@ -import datetime +import time +import json from flask import Response, Blueprint, request from firebase_admin import firestore + data = Blueprint('data', __name__) @data.route('/readings/save', methods=['POST']) @@ -13,7 +15,7 @@ def uploadReadings(): body = request.json if body is None: return Response("{'error':'Invalid request - please provide a body'}", status=400, mimetype='application/json') - body['timestamp'] = datetime.datetime.now() + body['timestamp'] = time.time() doc = firestore.client().collection(u'readings').document(deviceId).get() if doc.exists: @@ -26,3 +28,18 @@ def uploadReadings(): upload = {'data': data} firestore.client().collection(u'readings').document(deviceId).set(upload) return Response("{'success':'Data saved'}", status=200, mimetype='application/json') + +@data.route('/readings/getall', methods=['GET']) +def getAllReadings(): + deviceId = request.headers.get('deviceid') + if deviceId is None: + return Response("{'error':'Device not specified'}", status=400, mimetype='application/json') + + doc = firestore.client().collection(u'readings').document(deviceId).get() + if doc.exists: + data = doc.to_dict()['data'] + else: + data = [] + + results = {'data': data} + return Response(json.dumps(results), status=200, mimetype='application/json') From c661fe3595a2563a8fecc6d0b65995f758284751 Mon Sep 17 00:00:00 2001 From: Benjamin Ramhorst Date: Mon, 7 Feb 2022 14:06:56 +0000 Subject: [PATCH 13/17] Minor bug fix regarding JSON responses --- api/authentication.py | 23 ++++++++++++++--------- api/data.py | 13 ++++++++----- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/api/authentication.py b/api/authentication.py index 1da55cb..0aa80dd 100644 --- a/api/authentication.py +++ b/api/authentication.py @@ -10,7 +10,8 @@ authentication = Blueprint('authentication', __name__) def register(): body = request.json if body is None: - return Response("{'error':'Invalid request - please provide a body'}", status=400, mimetype='application/json') + resp = {'error': 'Invalid request - please provide a body'} + return Response(json.dumps(resp), status=400, mimetype='application/json') email = body['email'] password = body['password'] @@ -19,7 +20,8 @@ def register(): # Some fields are not present if email is None or password is None or name is None or deviceId is None: - return Response("{'error':'Entries missing'}", status=400, mimetype='application/json') + resp = {'error': 'Entries missing'} + return Response(json.dumps(resp), status=400, mimetype='application/json') # Register user with Firebase authentication try: @@ -30,8 +32,8 @@ def register(): display_name=name, disabled=False) except EmailAlreadyExistsError: - return Response("{'error':'User with given email address already exists'}", status=409, mimetype='application/json') - + resp = {'error': 'User with given email address already exists'} + return Response(json.dumps(resp), status=409, mimetype='application/json') # Prompt the user to get verified code = lib.utils.saveVerificationCode(user.uid) lib.utils.sendVerificationMail(name, email, code) @@ -50,7 +52,8 @@ def register(): def verify(): body = request.json if body is None: - return Response("{'error':'Invalid request - please provide a body'}", status=400, mimetype='application/json') + resp = {'error': 'Invalid request - please provide a body'} + return Response(json.dumps(resp), status=400, mimetype='application/json') uid = body['uid'] code = body['code'] @@ -60,12 +63,14 @@ def verify(): if doc.to_dict()['code'] == code: auth.update_user(uid, email_verified=True) firestore.client().collection(u'verification').document(uid).delete() - return Response("{'error':'User verified'}", status=200, mimetype='application/json') + resp = {'success': 'User verified'} + return Response(json.dumps(resp), status=200, mimetype='application/json') else: - return Response("{'error':'Invalid code'}", status=400, mimetype='application/json') + resp = {'error': 'Invalid code'} + return Response(json.dumps(resp), status=400, mimetype='application/json') else: user = auth.get_user(uid) code = lib.utils.saveVerificationCode(user.uid) lib.utils.sendVerificationMail(user.display_name, user.email, code) - return Response("{'error':'Server couldn't find code, creating new one and sending email'}", status=500, mimetype='application/json') - + resp = {'error': 'Server could not find code, creating new one and sending email'} + return Response(json.dumps(resp), status=500, mimetype='application/json') diff --git a/api/data.py b/api/data.py index 879f5ef..f140548 100644 --- a/api/data.py +++ b/api/data.py @@ -3,18 +3,19 @@ import json from flask import Response, Blueprint, request from firebase_admin import firestore - data = Blueprint('data', __name__) @data.route('/readings/save', methods=['POST']) def uploadReadings(): deviceId = request.headers.get('deviceid') if deviceId is None: - return Response("{'error':'Device not specified'}", status=400, mimetype='application/json') + resp = {'error': 'Device not specified'} + return Response(json.dumps(resp), status=400, mimetype='application/json') body = request.json if body is None: - return Response("{'error':'Invalid request - please provide a body'}", status=400, mimetype='application/json') + resp = {'error': 'Invalid request - please provide a body'} + return Response(json.dumps(resp), status=400, mimetype='application/json') body['timestamp'] = time.time() doc = firestore.client().collection(u'readings').document(deviceId).get() @@ -27,13 +28,15 @@ def uploadReadings(): upload = {'data': data} firestore.client().collection(u'readings').document(deviceId).set(upload) - return Response("{'success':'Data saved'}", status=200, mimetype='application/json') + resp = {'success': 'Data saved'} + return Response(json.dumps(resp), status=200, mimetype='application/json') @data.route('/readings/getall', methods=['GET']) def getAllReadings(): deviceId = request.headers.get('deviceid') if deviceId is None: - return Response("{'error':'Device not specified'}", status=400, mimetype='application/json') + resp = {'error': 'Device not specified'} + return Response(json.dumps(resp), status=400, mimetype='application/json') doc = firestore.client().collection(u'readings').document(deviceId).get() if doc.exists: From e3a612f207400eb17edd7ca4ad67f4c054afc26b Mon Sep 17 00:00:00 2001 From: Benjamin Ramhorst Date: Mon, 14 Feb 2022 20:16:37 +0000 Subject: [PATCH 14/17] Added endpoints for last location and total steps today --- api/data.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/api/data.py b/api/data.py index f140548..e8b47f0 100644 --- a/api/data.py +++ b/api/data.py @@ -46,3 +46,41 @@ def getAllReadings(): results = {'data': data} return Response(json.dumps(results), status=200, mimetype='application/json') + +@data.route('/readings/last/location', methods=['GET']) +def getLastLocation(): + deviceId = request.headers.get('deviceid') + if deviceId is None: + resp = {'error': 'Device not specified'} + return Response(json.dumps(resp), status=400, mimetype='application/json') + + doc = firestore.client().collection(u'readings').document(deviceId).get() + if doc.exists: + data = doc.to_dict()['data'] + lastEntry = data[-1] + lat = lastEntry['latitude'] + lon = lastEntry['longitude'] + else: + lat = -1.0 + lon = -1.0 + + results = {'latitude': lat, 'longitude': lon} + return Response(json.dumps(results), status=200, mimetype='application/json') + +@data.route('/readings/last/steps', methods=['GET']) +def getStepsToday(): + deviceId = request.headers.get('deviceid') + if deviceId is None: + resp = {'error': 'Device not specified'} + return Response(json.dumps(resp), status=400, mimetype='application/json') + + doc = firestore.client().collection(u'readings').document(deviceId).get() + if doc.exists: + data = doc.to_dict()['data'] + lastEntry = data[-1] + steps = lastEntry['cumulative_steps_today'] + else: + steps = 0 + + results = {'cumulative_steps_today': steps} + return Response(json.dumps(results), status=200, mimetype='application/json') From 78ac68cb2dca707f8a9e506fbf850c1efed83e38 Mon Sep 17 00:00:00 2001 From: Benjamin Ramhorst Date: Mon, 14 Feb 2022 21:14:22 +0000 Subject: [PATCH 15/17] =?UTF-8?q?Added=20functionality=20for=20reading=20l?= =?UTF-8?q?ast=205=20step=20counts=C2=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/data.py | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/api/data.py b/api/data.py index e8b47f0..4b4fb50 100644 --- a/api/data.py +++ b/api/data.py @@ -1,5 +1,6 @@ import time import json +from datetime import datetime, time, timedelta from flask import Response, Blueprint, request from firebase_admin import firestore @@ -12,12 +13,14 @@ def uploadReadings(): resp = {'error': 'Device not specified'} return Response(json.dumps(resp), status=400, mimetype='application/json') + # Check that measurements are provided body = request.json if body is None: resp = {'error': 'Invalid request - please provide a body'} return Response(json.dumps(resp), status=400, mimetype='application/json') body['timestamp'] = time.time() + # Save all the measurements doc = firestore.client().collection(u'readings').document(deviceId).get() if doc.exists: list = doc.to_dict()['data'] @@ -25,9 +28,9 @@ def uploadReadings(): data = list else: data = [body] - upload = {'data': data} firestore.client().collection(u'readings').document(deviceId).set(upload) + resp = {'success': 'Data saved'} return Response(json.dumps(resp), status=200, mimetype='application/json') @@ -47,7 +50,7 @@ def getAllReadings(): results = {'data': data} return Response(json.dumps(results), status=200, mimetype='application/json') -@data.route('/readings/last/location', methods=['GET']) +@data.route('/readings/location/last', methods=['GET']) def getLastLocation(): deviceId = request.headers.get('deviceid') if deviceId is None: @@ -67,7 +70,7 @@ def getLastLocation(): results = {'latitude': lat, 'longitude': lon} return Response(json.dumps(results), status=200, mimetype='application/json') -@data.route('/readings/last/steps', methods=['GET']) +@data.route('/readings/steps/today', methods=['GET']) def getStepsToday(): deviceId = request.headers.get('deviceid') if deviceId is None: @@ -84,3 +87,35 @@ def getStepsToday(): results = {'cumulative_steps_today': steps} return Response(json.dumps(results), status=200, mimetype='application/json') + +@data.route('/readings/steps/last-five-days', methods=['GET']) +def getStepsLastFiveDays(): + deviceId = request.headers.get('deviceid') + if deviceId is None: + resp = {'error': 'Device not specified'} + return Response(json.dumps(resp), status=400, mimetype='application/json') + + upcomingMidnight = datetime.combine(datetime.today(), time.min) + timedelta(days=1) + doc = firestore.client().collection(u'readings').document(deviceId).get() + + if doc.exists: + data = doc.to_dict()['data'] + listOfDailySteps = [] + + for i in range(0, 5): + found = False + previousMidnight = upcomingMidnight - timedelta(days=1) + print(previousMidnight.timestamp()) + steps = 0 + for reading in reversed(data): + if reading['timestamp'] <= upcomingMidnight.timestamp() and reading['timestamp'] >= previousMidnight.timestamp() and not found: + steps = reading['cumulative_steps_today'] + found = True + listOfDailySteps.append(steps) + upcomingMidnight = previousMidnight + else: + listOfDailySteps = [0] * 5 + + results = {'daily_steps': listOfDailySteps} + return Response(json.dumps(results), status=200, mimetype='application/json') + From 9851513288d6f69e1162e5fb34ed87315db9b1cf Mon Sep 17 00:00:00 2001 From: Benjamin Ramhorst Date: Tue, 15 Feb 2022 00:10:56 +0000 Subject: [PATCH 16/17] Added endpoint for metric summary --- api/data.py | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/api/data.py b/api/data.py index 4b4fb50..ff16579 100644 --- a/api/data.py +++ b/api/data.py @@ -18,7 +18,7 @@ def uploadReadings(): if body is None: resp = {'error': 'Invalid request - please provide a body'} return Response(json.dumps(resp), status=400, mimetype='application/json') - body['timestamp'] = time.time() + body['timestamp'] = datetime.now().timestamp() # Save all the measurements doc = firestore.client().collection(u'readings').document(deviceId).get() @@ -119,3 +119,38 @@ def getStepsLastFiveDays(): results = {'daily_steps': listOfDailySteps} return Response(json.dumps(results), status=200, mimetype='application/json') +@data.route('/readings/metrics-summary', methods=['GET']) +def getMetricsSummary(): + deviceId = request.headers.get('deviceid') + if deviceId is None: + resp = {'error': 'Device not specified'} + return Response(json.dumps(resp), status=400, mimetype='application/json') + + upcomingMidnight = datetime.combine(datetime.today(), time.min) #+ timedelta(days=1) + lastMidnight = datetime.combine(datetime.today(), time.min) - timedelta(days=1) + doc = firestore.client().collection(u'readings').document(deviceId).get() + + if doc.exists: + allData = doc.to_dict()['data'] + currentDayData = [x for x in allData if x['timestamp'] <= upcomingMidnight.timestamp() and x['timestamp'] >= lastMidnight.timestamp()] + if len(currentDayData) >= 1: + maxAirTemp = max(currentDayData, key=lambda x: x['air_temp'])['air_temp'] + maxSkinTemp = max(currentDayData, key=lambda x: x['skin_temp'])['skin_temp'] + maxHumidity = max(currentDayData, key=lambda x: x['humidity'])['humidity'] + minAirTemp = min(currentDayData, key=lambda x: x['air_temp'])['air_temp'] + minSkinTemp = min(currentDayData, key=lambda x: x['skin_temp'])['skin_temp'] + minHumidity = min(currentDayData, key=lambda x: x['humidity'])['humidity'] + results = { + 'last_air_temp': currentDayData[-1]['air_temp'], 'min_air_temp': minAirTemp, 'max_air_temp': maxAirTemp, + 'last_skin_temp': currentDayData[-1]['skin_temp'], 'min_skin_temp': minSkinTemp, 'max_skin_temp': maxSkinTemp, + 'last_humidity': currentDayData[-1]['humidity'], 'min_humidity': minHumidity, 'max_humidity': maxHumidity + } + return Response(json.dumps(results), status=200, mimetype='application/json') + else: + return Response(json.dumps({'error': 'Could not get data from database'}), status=500, mimetype='application/json') + else: + return Response(json.dumps({'error': 'Could not get data from database'}), status=500, mimetype='application/json') + + + + From 2f770d1098781b077b75ef46985c4dd252c7882b Mon Sep 17 00:00:00 2001 From: Benjamin Ramhorst Date: Tue, 1 Mar 2022 11:06:43 +0000 Subject: [PATCH 17/17] Minor fix --- api/authentication.py | 17 +++++++++++++++++ api/data.py | 16 ++++++++-------- lib/utils.py | 9 +-------- main.py | 1 - 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/api/authentication.py b/api/authentication.py index 0aa80dd..0ad9b04 100644 --- a/api/authentication.py +++ b/api/authentication.py @@ -74,3 +74,20 @@ def verify(): lib.utils.sendVerificationMail(user.display_name, user.email, code) resp = {'error': 'Server could not find code, creating new one and sending email'} return Response(json.dumps(resp), status=500, mimetype='application/json') + +@authentication.route('/authentication/get-user-devices', methods=['GET']) +def uploadReadings(): + uid = request.headers.get('UID') + if uid is None: + resp = {'error': 'UID not specified'} + return Response(json.dumps(resp), status=400, mimetype='application/json') + + # Save all the measurements + doc = firestore.client().collection(u'devices').document(uid).get() + if doc.exists: + list = doc.to_dict()['devices'] + data = list + else: + data = [] + res = {'devices': data} + return Response(json.dumps(res), status=200, mimetype='application/json') diff --git a/api/data.py b/api/data.py index ff16579..629cf53 100644 --- a/api/data.py +++ b/api/data.py @@ -8,7 +8,7 @@ data = Blueprint('data', __name__) @data.route('/readings/save', methods=['POST']) def uploadReadings(): - deviceId = request.headers.get('deviceid') + deviceId = request.headers.get('Device-ID') if deviceId is None: resp = {'error': 'Device not specified'} return Response(json.dumps(resp), status=400, mimetype='application/json') @@ -36,7 +36,7 @@ def uploadReadings(): @data.route('/readings/getall', methods=['GET']) def getAllReadings(): - deviceId = request.headers.get('deviceid') + deviceId = request.headers.get('Device-ID') if deviceId is None: resp = {'error': 'Device not specified'} return Response(json.dumps(resp), status=400, mimetype='application/json') @@ -52,7 +52,7 @@ def getAllReadings(): @data.route('/readings/location/last', methods=['GET']) def getLastLocation(): - deviceId = request.headers.get('deviceid') + deviceId = request.headers.get('Device-ID') if deviceId is None: resp = {'error': 'Device not specified'} return Response(json.dumps(resp), status=400, mimetype='application/json') @@ -72,7 +72,7 @@ def getLastLocation(): @data.route('/readings/steps/today', methods=['GET']) def getStepsToday(): - deviceId = request.headers.get('deviceid') + deviceId = request.headers.get('Device-ID') if deviceId is None: resp = {'error': 'Device not specified'} return Response(json.dumps(resp), status=400, mimetype='application/json') @@ -90,7 +90,7 @@ def getStepsToday(): @data.route('/readings/steps/last-five-days', methods=['GET']) def getStepsLastFiveDays(): - deviceId = request.headers.get('deviceid') + deviceId = request.headers.get('Device-ID') if deviceId is None: resp = {'error': 'Device not specified'} return Response(json.dumps(resp), status=400, mimetype='application/json') @@ -121,13 +121,13 @@ def getStepsLastFiveDays(): @data.route('/readings/metrics-summary', methods=['GET']) def getMetricsSummary(): - deviceId = request.headers.get('deviceid') + deviceId = request.headers.get('Device-ID') if deviceId is None: resp = {'error': 'Device not specified'} return Response(json.dumps(resp), status=400, mimetype='application/json') - upcomingMidnight = datetime.combine(datetime.today(), time.min) #+ timedelta(days=1) - lastMidnight = datetime.combine(datetime.today(), time.min) - timedelta(days=1) + upcomingMidnight = datetime.combine(datetime.today(), time.min) + timedelta(days=1) + lastMidnight = datetime.combine(datetime.today(), time.min) doc = firestore.client().collection(u'readings').document(deviceId).get() if doc.exists: diff --git a/lib/utils.py b/lib/utils.py index ba7fbbf..2488e41 100644 --- a/lib/utils.py +++ b/lib/utils.py @@ -1,7 +1,7 @@ from random import randint from flask import current_app from flask_mail import Mail, Message -from firebase_admin import auth, firestore +from firebase_admin import firestore def sendMail(subject, sender, recipients, body): mail = Mail(current_app) @@ -24,10 +24,3 @@ def sendVerificationMail(name, email, code): body = '''Hey {}! Thank you for signing up for BarkFinder. In order to use our sevices, could you please verify your email address by logging in and entering this code {}'''.format(name, code) sendMail(subject, sender, recipients, body) - -def userLoggedInAndVerfied(token): - # Need frontend to test this - # decoded_token = auth.verify_id_token(token) - # uid = decoded_token['uid'] - # isVerified = auth.get_user(uid).email_verified - return True #placeholder \ No newline at end of file diff --git a/main.py b/main.py index fc5d5fb..779d57e 100644 --- a/main.py +++ b/main.py @@ -9,7 +9,6 @@ app = Flask(__name__) app.register_blueprint(authentication) app.register_blueprint(data) - # Initialize Mail instance app.config['MAIL_SERVER'] = MAIL_SERVER app.config['MAIL_PORT'] = MAIL_PORT