We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
HTTP 500 on /oauth/<provider>
**Describe the bug**
<!-- A clear and concise description of what the bug is. -->
The server returns HTTP 500 when a request is made to /oauth/<provider>. It is probably because I haven't configured facebook keys in the settings.

**Expected behavior**
<!-- A clear and concise description of what you expected to happen. -->
It shouldn't error out in any case. If something is improperly configured then it should return that message rather than the HTTP 500.

**Stacktrace**
```
INFO:werkzeug:127.0.0.1 - - [17/Jul/2018 04:40:54] "GET /v1/auth/oauth/facebook HTTP/1.1" 500 -
Traceback (most recent call last):
  File "/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__
    return self.wsgi_app(environ, start_response)
  File "/media/srv_twry/work/Projects/Community-Projects/Fossasia/open-event-server/app/__init__.py", line 66, in __call__
    return self.app(environ, start_response)
  File "/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app
    response = self.handle_exception(e)
  File "/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask_cors/extension.py", line 161, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask_cors/extension.py", line 161, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  File "/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask_cors/extension.py", line 161, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask_cors/extension.py", line 161, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise
    raise value
  File "/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/media/srv_twry/work/Projects/Community-Projects/Fossasia/open-event-server/app/api/auth.py", line 39, in redirect_uri
    provider_class.get_client_id() + '&redirect_uri=' +\
TypeError: must be str, not NoneType
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `app/api/auth.py`
Content:
```
1 import base64
2 from flask import request, jsonify, make_response, Blueprint
3 from flask_jwt import current_identity as current_user, jwt_required
4 from sqlalchemy.orm.exc import NoResultFound
5 import requests
6 
7 from app import get_settings
8 from app.api.helpers.db import save_to_db
9 from app.api.helpers.files import make_frontend_url
10 from app.api.helpers.mail import send_email_with_action, \
11                                  send_email_confirmation
12 from app.api.helpers.notification import send_notification_with_action
13 
14 from app.api.helpers.utilities import get_serializer, str_generator
15 from app.models.mail import PASSWORD_RESET, PASSWORD_CHANGE, \
16                             USER_REGISTER_WITH_PASSWORD
17 from app.models.notification import PASSWORD_CHANGE as PASSWORD_CHANGE_NOTIF
18 from app.models.user import User
19 from app.api.helpers.errors import UnprocessableEntityError, NotFoundError, BadRequestError
20 from app.api.helpers.third_party_auth import GoogleOAuth, FbOAuth, TwitterOAuth, InstagramOAuth
21 
22 auth_routes = Blueprint('auth', __name__, url_prefix='/v1/auth')
23 
24 
25 @auth_routes.route('/oauth/<provider>', methods=['GET'])
26 def redirect_uri(provider):
27     if provider == 'facebook':
28         provider_class = FbOAuth()
29     elif provider == 'google':
30         provider_class = GoogleOAuth()
31     elif provider == 'twitter':
32         provider_class = TwitterOAuth()
33     elif provider == 'instagram':
34         provider_class = InstagramOAuth()
35     else:
36         return make_response(jsonify(
37             message="No support for {}".format(provider)), 404)
38     url = provider_class.get_auth_uri() + '?client_id=' +\
39         provider_class.get_client_id() + '&redirect_uri=' +\
40         provider_class.get_redirect_uri()
41     return make_response(jsonify(url=url), 200)
42 
43 
44 @auth_routes.route('/oauth/token/<provider>', methods=['GET'])
45 def get_token(provider):
46     if provider == 'facebook':
47         provider_class = FbOAuth()
48         payload = {
49             'grant_type': 'client_credentials',
50             'client_id': provider_class.get_client_id(),
51             'client_secret': provider_class.get_client_secret()
52         }
53     elif provider == 'google':
54         provider_class = GoogleOAuth()
55         payload = {
56             'client_id': provider_class.get_client_id(),
57             'client_secret': provider_class.get_client_secret()
58         }
59     elif provider == 'twitter':
60         provider_class = TwitterOAuth()
61         payload = {
62             'client_id': provider_class.get_client_id(),
63             'client_secret': provider_class.get_client_secret()
64         }
65     elif provider == 'instagram':
66         provider_class = InstagramOAuth()
67         payload = {
68             'client_id': provider_class.get_client_id(),
69             'client_secret': provider_class.get_client_secret()
70         }
71     else:
72         return make_response(jsonify(
73             message="No support for {}".format(provider)), 200)
74     response = requests.post(provider_class.get_token_uri(), params=payload)
75     return make_response(jsonify(token=response.json()), 200)
76 
77 
78 @auth_routes.route('/verify-email', methods=['POST'])
79 def verify_email():
80     token = base64.b64decode(request.json['data']['token'])
81     s = get_serializer()
82 
83     try:
84         data = s.loads(token)
85     except Exception:
86         return BadRequestError({'source': ''}, 'Invalid Token').respond()
87 
88     try:
89         user = User.query.filter_by(email=data[0]).one()
90     except Exception:
91         return BadRequestError({'source': ''}, 'Invalid Token').respond()
92     else:
93         user.is_verified = True
94         save_to_db(user)
95         return make_response(jsonify(message="Email Verified"), 200)
96 
97 
98 @auth_routes.route('/resend-verification-email', methods=['POST'])
99 def resend_verification_email():
100     try:
101         email = request.json['data']['email']
102     except TypeError:
103         return BadRequestError({'source': ''}, 'Bad Request Error').respond()
104 
105     try:
106         user = User.query.filter_by(email=email).one()
107     except NoResultFound:
108         return UnprocessableEntityError(
109             {'source': ''}, 'User with email: ' + email + ' not found.').respond()
110     else:
111         serializer = get_serializer()
112         hash_ = str(base64.b64encode(str(serializer.dumps(
113             [user.email, str_generator()])).encode()), 'utf-8')
114         link = make_frontend_url(
115             '/email/verify'.format(id=user.id), {'token': hash_})
116         send_email_with_action(
117             user, USER_REGISTER_WITH_PASSWORD,
118             app_name=get_settings()['app_name'], email=user.email)
119         send_email_confirmation(user.email, link)
120 
121         return make_response(jsonify(message="Verification email resent"), 200)
122 
123 
124 @auth_routes.route('/reset-password', methods=['POST'])
125 def reset_password_post():
126     try:
127         email = request.json['data']['email']
128     except TypeError:
129         return BadRequestError({'source': ''}, 'Bad Request Error').respond()
130 
131     try:
132         user = User.query.filter_by(email=email).one()
133     except NoResultFound:
134         return UnprocessableEntityError({'source': ''}, 'User not found').respond()
135     else:
136         link = make_frontend_url('/reset-password', {'token': user.reset_password})
137         send_email_with_action(user, PASSWORD_RESET, app_name=get_settings()['app_name'], link=link)
138 
139     return make_response(jsonify(message="Email Sent"), 200)
140 
141 
142 @auth_routes.route('/reset-password', methods=['PATCH'])
143 def reset_password_patch():
144     token = request.json['data']['token']
145     password = request.json['data']['password']
146 
147     try:
148         user = User.query.filter_by(reset_password=token).one()
149     except NoResultFound:
150         return NotFoundError({'source': ''}, 'User Not Found').respond()
151     else:
152         user.password = password
153         save_to_db(user)
154 
155     return jsonify({
156         "id": user.id,
157         "email": user.email,
158         "name": user.fullname if user.fullname else None
159     })
160 
161 
162 @auth_routes.route('/change-password', methods=['POST'])
163 @jwt_required()
164 def change_password():
165     old_password = request.json['data']['old-password']
166     new_password = request.json['data']['new-password']
167 
168     try:
169         user = User.query.filter_by(id=current_user.id).one()
170     except NoResultFound:
171         return NotFoundError({'source': ''}, 'User Not Found').respond()
172     else:
173         if user.is_correct_password(old_password):
174 
175             user.password = new_password
176             save_to_db(user)
177             send_email_with_action(user, PASSWORD_CHANGE,
178                                    app_name=get_settings()['app_name'])
179             send_notification_with_action(user, PASSWORD_CHANGE_NOTIF,
180                                    app_name=get_settings()['app_name'])
181         else:
182             return BadRequestError({'source': ''}, 'Wrong Password').respond()
183 
184     return jsonify({
185         "id": user.id,
186         "email": user.email,
187         "name": user.fullname if user.fullname else None,
188         "password-changed": True
189     })
190
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/app/api/auth.py b/app/api/auth.py
--- a/app/api/auth.py
+++ b/app/api/auth.py
@@ -35,8 +35,14 @@
     else:
         return make_response(jsonify(
             message="No support for {}".format(provider)), 404)
+
+    client_id = provider_class.get_client_id()
+    if not client_id:
+        return make_response(jsonify(
+            message="{} client id is not configured on the server".format(provider)), 404)
+
     url = provider_class.get_auth_uri() + '?client_id=' +\
-        provider_class.get_client_id() + '&redirect_uri=' +\
+        client_id + '&redirect_uri=' +\
         provider_class.get_redirect_uri()
     return make_response(jsonify(url=url), 200)

{"golden_diff": "diff --git a/app/api/auth.py b/app/api/auth.py\n--- a/app/api/auth.py\n+++ b/app/api/auth.py\n@@ -35,8 +35,14 @@\n     else:\n         return make_response(jsonify(\n             message=\"No support for {}\".format(provider)), 404)\n+\n+    client_id = provider_class.get_client_id()\n+    if not client_id:\n+        return make_response(jsonify(\n+            message=\"{} client id is not configured on the server\".format(provider)), 404)\n+\n     url = provider_class.get_auth_uri() + '?client_id=' +\\\n-        provider_class.get_client_id() + '&redirect_uri=' +\\\n+        client_id + '&redirect_uri=' +\\\n         provider_class.get_redirect_uri()\n     return make_response(jsonify(url=url), 200)\n", "issue": "HTTP 500 on /oauth/<provider>\n**Describe the bug**\r\n<!-- A clear and concise description of what the bug is. -->\r\nThe server returns HTTP 500 when a request is made to /oauth/<provider>. It is probably because I haven't configured facebook keys in the settings.\r\n\r\n**Expected behavior**\r\n<!-- A clear and concise description of what you expected to happen. -->\r\nIt shouldn't error out in any case. If something is improperly configured then it should return that message rather than the HTTP 500.\r\n\r\n**Stacktrace**\r\n```\r\nINFO:werkzeug:127.0.0.1 - - [17/Jul/2018 04:40:54] \"GET /v1/auth/oauth/facebook HTTP/1.1\" 500 -\r\nTraceback (most recent call last):\r\n  File \"/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/app.py\", line 2309, in __call__\r\n    return self.wsgi_app(environ, start_response)\r\n  File \"/media/srv_twry/work/Projects/Community-Projects/Fossasia/open-event-server/app/__init__.py\", line 66, in __call__\r\n    return self.app(environ, start_response)\r\n  File \"/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/app.py\", line 2295, in wsgi_app\r\n    response = self.handle_exception(e)\r\n  File \"/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask_cors/extension.py\", line 161, in wrapped_function\r\n    return cors_after_request(app.make_response(f(*args, **kwargs)))\r\n  File \"/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask_cors/extension.py\", line 161, in wrapped_function\r\n    return cors_after_request(app.make_response(f(*args, **kwargs)))\r\n  File \"/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/app.py\", line 1741, in handle_exception\r\n    reraise(exc_type, exc_value, tb)\r\n  File \"/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/_compat.py\", line 35, in reraise\r\n    raise value\r\n  File \"/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/app.py\", line 2292, in wsgi_app\r\n    response = self.full_dispatch_request()\r\n  File \"/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/app.py\", line 1815, in full_dispatch_request\r\n    rv = self.handle_user_exception(e)\r\n  File \"/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask_cors/extension.py\", line 161, in wrapped_function\r\n    return cors_after_request(app.make_response(f(*args, **kwargs)))\r\n  File \"/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask_cors/extension.py\", line 161, in wrapped_function\r\n    return cors_after_request(app.make_response(f(*args, **kwargs)))\r\n  File \"/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/app.py\", line 1718, in handle_user_exception\r\n    reraise(exc_type, exc_value, tb)\r\n  File \"/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/_compat.py\", line 35, in reraise\r\n    raise value\r\n  File \"/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/app.py\", line 1813, in full_dispatch_request\r\n    rv = self.dispatch_request()\r\n  File \"/home/srv_twry/anaconda3/envs/open-event-server/lib/python3.6/site-packages/flask/app.py\", line 1799, in dispatch_request\r\n    return self.view_functions[rule.endpoint](**req.view_args)\r\n  File \"/media/srv_twry/work/Projects/Community-Projects/Fossasia/open-event-server/app/api/auth.py\", line 39, in redirect_uri\r\n    provider_class.get_client_id() + '&redirect_uri=' +\\\r\nTypeError: must be str, not NoneType\r\n```\n", "before_files": [{"content": "import base64\nfrom flask import request, jsonify, make_response, Blueprint\nfrom flask_jwt import current_identity as current_user, jwt_required\nfrom sqlalchemy.orm.exc import NoResultFound\nimport requests\n\nfrom app import get_settings\nfrom app.api.helpers.db import save_to_db\nfrom app.api.helpers.files import make_frontend_url\nfrom app.api.helpers.mail import send_email_with_action, \\\n                                 send_email_confirmation\nfrom app.api.helpers.notification import send_notification_with_action\n\nfrom app.api.helpers.utilities import get_serializer, str_generator\nfrom app.models.mail import PASSWORD_RESET, PASSWORD_CHANGE, \\\n                            USER_REGISTER_WITH_PASSWORD\nfrom app.models.notification import PASSWORD_CHANGE as PASSWORD_CHANGE_NOTIF\nfrom app.models.user import User\nfrom app.api.helpers.errors import UnprocessableEntityError, NotFoundError, BadRequestError\nfrom app.api.helpers.third_party_auth import GoogleOAuth, FbOAuth, TwitterOAuth, InstagramOAuth\n\nauth_routes = Blueprint('auth', __name__, url_prefix='/v1/auth')\n\n\n@auth_routes.route('/oauth/<provider>', methods=['GET'])\ndef redirect_uri(provider):\n    if provider == 'facebook':\n        provider_class = FbOAuth()\n    elif provider == 'google':\n        provider_class = GoogleOAuth()\n    elif provider == 'twitter':\n        provider_class = TwitterOAuth()\n    elif provider == 'instagram':\n        provider_class = InstagramOAuth()\n    else:\n        return make_response(jsonify(\n            message=\"No support for {}\".format(provider)), 404)\n    url = provider_class.get_auth_uri() + '?client_id=' +\\\n        provider_class.get_client_id() + '&redirect_uri=' +\\\n        provider_class.get_redirect_uri()\n    return make_response(jsonify(url=url), 200)\n\n\n@auth_routes.route('/oauth/token/<provider>', methods=['GET'])\ndef get_token(provider):\n    if provider == 'facebook':\n        provider_class = FbOAuth()\n        payload = {\n            'grant_type': 'client_credentials',\n            'client_id': provider_class.get_client_id(),\n            'client_secret': provider_class.get_client_secret()\n        }\n    elif provider == 'google':\n        provider_class = GoogleOAuth()\n        payload = {\n            'client_id': provider_class.get_client_id(),\n            'client_secret': provider_class.get_client_secret()\n        }\n    elif provider == 'twitter':\n        provider_class = TwitterOAuth()\n        payload = {\n            'client_id': provider_class.get_client_id(),\n            'client_secret': provider_class.get_client_secret()\n        }\n    elif provider == 'instagram':\n        provider_class = InstagramOAuth()\n        payload = {\n            'client_id': provider_class.get_client_id(),\n            'client_secret': provider_class.get_client_secret()\n        }\n    else:\n        return make_response(jsonify(\n            message=\"No support for {}\".format(provider)), 200)\n    response = requests.post(provider_class.get_token_uri(), params=payload)\n    return make_response(jsonify(token=response.json()), 200)\n\n\n@auth_routes.route('/verify-email', methods=['POST'])\ndef verify_email():\n    token = base64.b64decode(request.json['data']['token'])\n    s = get_serializer()\n\n    try:\n        data = s.loads(token)\n    except Exception:\n        return BadRequestError({'source': ''}, 'Invalid Token').respond()\n\n    try:\n        user = User.query.filter_by(email=data[0]).one()\n    except Exception:\n        return BadRequestError({'source': ''}, 'Invalid Token').respond()\n    else:\n        user.is_verified = True\n        save_to_db(user)\n        return make_response(jsonify(message=\"Email Verified\"), 200)\n\n\n@auth_routes.route('/resend-verification-email', methods=['POST'])\ndef resend_verification_email():\n    try:\n        email = request.json['data']['email']\n    except TypeError:\n        return BadRequestError({'source': ''}, 'Bad Request Error').respond()\n\n    try:\n        user = User.query.filter_by(email=email).one()\n    except NoResultFound:\n        return UnprocessableEntityError(\n            {'source': ''}, 'User with email: ' + email + ' not found.').respond()\n    else:\n        serializer = get_serializer()\n        hash_ = str(base64.b64encode(str(serializer.dumps(\n            [user.email, str_generator()])).encode()), 'utf-8')\n        link = make_frontend_url(\n            '/email/verify'.format(id=user.id), {'token': hash_})\n        send_email_with_action(\n            user, USER_REGISTER_WITH_PASSWORD,\n            app_name=get_settings()['app_name'], email=user.email)\n        send_email_confirmation(user.email, link)\n\n        return make_response(jsonify(message=\"Verification email resent\"), 200)\n\n\n@auth_routes.route('/reset-password', methods=['POST'])\ndef reset_password_post():\n    try:\n        email = request.json['data']['email']\n    except TypeError:\n        return BadRequestError({'source': ''}, 'Bad Request Error').respond()\n\n    try:\n        user = User.query.filter_by(email=email).one()\n    except NoResultFound:\n        return UnprocessableEntityError({'source': ''}, 'User not found').respond()\n    else:\n        link = make_frontend_url('/reset-password', {'token': user.reset_password})\n        send_email_with_action(user, PASSWORD_RESET, app_name=get_settings()['app_name'], link=link)\n\n    return make_response(jsonify(message=\"Email Sent\"), 200)\n\n\n@auth_routes.route('/reset-password', methods=['PATCH'])\ndef reset_password_patch():\n    token = request.json['data']['token']\n    password = request.json['data']['password']\n\n    try:\n        user = User.query.filter_by(reset_password=token).one()\n    except NoResultFound:\n        return NotFoundError({'source': ''}, 'User Not Found').respond()\n    else:\n        user.password = password\n        save_to_db(user)\n\n    return jsonify({\n        \"id\": user.id,\n        \"email\": user.email,\n        \"name\": user.fullname if user.fullname else None\n    })\n\n\n@auth_routes.route('/change-password', methods=['POST'])\n@jwt_required()\ndef change_password():\n    old_password = request.json['data']['old-password']\n    new_password = request.json['data']['new-password']\n\n    try:\n        user = User.query.filter_by(id=current_user.id).one()\n    except NoResultFound:\n        return NotFoundError({'source': ''}, 'User Not Found').respond()\n    else:\n        if user.is_correct_password(old_password):\n\n            user.password = new_password\n            save_to_db(user)\n            send_email_with_action(user, PASSWORD_CHANGE,\n                                   app_name=get_settings()['app_name'])\n            send_notification_with_action(user, PASSWORD_CHANGE_NOTIF,\n                                   app_name=get_settings()['app_name'])\n        else:\n            return BadRequestError({'source': ''}, 'Wrong Password').respond()\n\n    return jsonify({\n        \"id\": user.id,\n        \"email\": user.email,\n        \"name\": user.fullname if user.fullname else None,\n        \"password-changed\": True\n    })\n", "path": "app/api/auth.py"}], "after_files": [{"content": "import base64\nfrom flask import request, jsonify, make_response, Blueprint\nfrom flask_jwt import current_identity as current_user, jwt_required\nfrom sqlalchemy.orm.exc import NoResultFound\nimport requests\n\nfrom app import get_settings\nfrom app.api.helpers.db import save_to_db\nfrom app.api.helpers.files import make_frontend_url\nfrom app.api.helpers.mail import send_email_with_action, \\\n                                 send_email_confirmation\nfrom app.api.helpers.notification import send_notification_with_action\n\nfrom app.api.helpers.utilities import get_serializer, str_generator\nfrom app.models.mail import PASSWORD_RESET, PASSWORD_CHANGE, \\\n                            USER_REGISTER_WITH_PASSWORD\nfrom app.models.notification import PASSWORD_CHANGE as PASSWORD_CHANGE_NOTIF\nfrom app.models.user import User\nfrom app.api.helpers.errors import UnprocessableEntityError, NotFoundError, BadRequestError\nfrom app.api.helpers.third_party_auth import GoogleOAuth, FbOAuth, TwitterOAuth, InstagramOAuth\n\nauth_routes = Blueprint('auth', __name__, url_prefix='/v1/auth')\n\n\n@auth_routes.route('/oauth/<provider>', methods=['GET'])\ndef redirect_uri(provider):\n    if provider == 'facebook':\n        provider_class = FbOAuth()\n    elif provider == 'google':\n        provider_class = GoogleOAuth()\n    elif provider == 'twitter':\n        provider_class = TwitterOAuth()\n    elif provider == 'instagram':\n        provider_class = InstagramOAuth()\n    else:\n        return make_response(jsonify(\n            message=\"No support for {}\".format(provider)), 404)\n\n    client_id = provider_class.get_client_id()\n    if not client_id:\n        return make_response(jsonify(\n            message=\"{} client id is not configured on the server\".format(provider)), 404)\n\n    url = provider_class.get_auth_uri() + '?client_id=' +\\\n        client_id + '&redirect_uri=' +\\\n        provider_class.get_redirect_uri()\n    return make_response(jsonify(url=url), 200)\n\n\n@auth_routes.route('/oauth/token/<provider>', methods=['GET'])\ndef get_token(provider):\n    if provider == 'facebook':\n        provider_class = FbOAuth()\n        payload = {\n            'grant_type': 'client_credentials',\n            'client_id': provider_class.get_client_id(),\n            'client_secret': provider_class.get_client_secret()\n        }\n    elif provider == 'google':\n        provider_class = GoogleOAuth()\n        payload = {\n            'client_id': provider_class.get_client_id(),\n            'client_secret': provider_class.get_client_secret()\n        }\n    elif provider == 'twitter':\n        provider_class = TwitterOAuth()\n        payload = {\n            'client_id': provider_class.get_client_id(),\n            'client_secret': provider_class.get_client_secret()\n        }\n    elif provider == 'instagram':\n        provider_class = InstagramOAuth()\n        payload = {\n            'client_id': provider_class.get_client_id(),\n            'client_secret': provider_class.get_client_secret()\n        }\n    else:\n        return make_response(jsonify(\n            message=\"No support for {}\".format(provider)), 200)\n    response = requests.post(provider_class.get_token_uri(), params=payload)\n    return make_response(jsonify(token=response.json()), 200)\n\n\n@auth_routes.route('/verify-email', methods=['POST'])\ndef verify_email():\n    token = base64.b64decode(request.json['data']['token'])\n    s = get_serializer()\n\n    try:\n        data = s.loads(token)\n    except Exception:\n        return BadRequestError({'source': ''}, 'Invalid Token').respond()\n\n    try:\n        user = User.query.filter_by(email=data[0]).one()\n    except Exception:\n        return BadRequestError({'source': ''}, 'Invalid Token').respond()\n    else:\n        user.is_verified = True\n        save_to_db(user)\n        return make_response(jsonify(message=\"Email Verified\"), 200)\n\n\n@auth_routes.route('/resend-verification-email', methods=['POST'])\ndef resend_verification_email():\n    try:\n        email = request.json['data']['email']\n    except TypeError:\n        return BadRequestError({'source': ''}, 'Bad Request Error').respond()\n\n    try:\n        user = User.query.filter_by(email=email).one()\n    except NoResultFound:\n        return UnprocessableEntityError(\n            {'source': ''}, 'User with email: ' + email + ' not found.').respond()\n    else:\n        serializer = get_serializer()\n        hash_ = str(base64.b64encode(str(serializer.dumps(\n            [user.email, str_generator()])).encode()), 'utf-8')\n        link = make_frontend_url(\n            '/email/verify'.format(id=user.id), {'token': hash_})\n        send_email_with_action(\n            user, USER_REGISTER_WITH_PASSWORD,\n            app_name=get_settings()['app_name'], email=user.email)\n        send_email_confirmation(user.email, link)\n\n        return make_response(jsonify(message=\"Verification email resent\"), 200)\n\n\n@auth_routes.route('/reset-password', methods=['POST'])\ndef reset_password_post():\n    try:\n        email = request.json['data']['email']\n    except TypeError:\n        return BadRequestError({'source': ''}, 'Bad Request Error').respond()\n\n    try:\n        user = User.query.filter_by(email=email).one()\n    except NoResultFound:\n        return UnprocessableEntityError({'source': ''}, 'User not found').respond()\n    else:\n        link = make_frontend_url('/reset-password', {'token': user.reset_password})\n        send_email_with_action(user, PASSWORD_RESET, app_name=get_settings()['app_name'], link=link)\n\n    return make_response(jsonify(message=\"Email Sent\"), 200)\n\n\n@auth_routes.route('/reset-password', methods=['PATCH'])\ndef reset_password_patch():\n    token = request.json['data']['token']\n    password = request.json['data']['password']\n\n    try:\n        user = User.query.filter_by(reset_password=token).one()\n    except NoResultFound:\n        return NotFoundError({'source': ''}, 'User Not Found').respond()\n    else:\n        user.password = password\n        save_to_db(user)\n\n    return jsonify({\n        \"id\": user.id,\n        \"email\": user.email,\n        \"name\": user.fullname if user.fullname else None\n    })\n\n\n@auth_routes.route('/change-password', methods=['POST'])\n@jwt_required()\ndef change_password():\n    old_password = request.json['data']['old-password']\n    new_password = request.json['data']['new-password']\n\n    try:\n        user = User.query.filter_by(id=current_user.id).one()\n    except NoResultFound:\n        return NotFoundError({'source': ''}, 'User Not Found').respond()\n    else:\n        if user.is_correct_password(old_password):\n\n            user.password = new_password\n            save_to_db(user)\n            send_email_with_action(user, PASSWORD_CHANGE,\n                                   app_name=get_settings()['app_name'])\n            send_notification_with_action(user, PASSWORD_CHANGE_NOTIF,\n                                   app_name=get_settings()['app_name'])\n        else:\n            return BadRequestError({'source': ''}, 'Wrong Password').respond()\n\n    return jsonify({\n        \"id\": user.id,\n        \"email\": user.email,\n        \"name\": user.fullname if user.fullname else None,\n        \"password-changed\": True\n    })\n", "path": "app/api/auth.py"}]}