Skip to content

Commit d714121

Browse files
Merge pull request #7 from pratapaprasanna/feature/addtoken
[Feature] add token and expiration capabilities
2 parents 56c2c3e + 3b01378 commit d714121

File tree

10 files changed

+463
-56
lines changed

10 files changed

+463
-56
lines changed

README.md

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
## UseCase
2-
- Any idea or application a developer wants to develop. He has to put-in efforts to develop an authenticator using which a user signs up to the app.
2+
- Any idea or application a developer wants to develop. He has to put-in efforts to develop an authenticator using which a user signs up to the app.
33
- Authenticator is just that component which adds user to a db and validates if any request is coming from a person belonging to the application.
44

55
In signup you have multiple ways of doing it
@@ -24,28 +24,43 @@ Some other day we want to work on some idea we should be able to use this authen
2424
- python
2525
- Kubernetes (Soon once the working prototype is ready)
2626

27-
### ENV setup
27+
### ENV setup
2828
- docker-compose up
2929

3030
Post this start making changes to the code they should be reflected and you should be able to see them running.
3131

32-
### Current-state:
32+
### Local Setup
33+
34+
##### Run
35+
36+
- ```pip install poetry```
37+
- ```poetry install```
38+
- ```poetry run python authenticator/app.py```
39+
40+
### Current-state:
3341
In the repo you see signup with google until now. Moving forward we should add the ability to signup with facebook/twitter
3442

3543
## User Journey
3644
### Google login
3745
- When user wishes to sign-up
3846

39-
![WhatsApp Image 2021-07-28 at 6 44 16 PM](https://user-images.githubusercontent.com/15846947/127329000-12621164-ba6d-4775-bd40-8c9f4395ed59.jpeg)
47+
![1](https://user-images.githubusercontent.com/15846947/130355612-d9974e00-f6c2-4418-916d-907d9064b9b4.png)
48+
4049

4150
- Authorize with gmail/google login
42-
![2](https://user-images.githubusercontent.com/15846947/127329338-7e20218f-cccb-4059-817a-c27fdce6510d.jpeg)
51+
![3](https://user-images.githubusercontent.com/15846947/130355624-3777ce21-7ba2-41b4-9c8c-ef922a4a89ef.png)
52+
53+
54+
- auth-token generated
55+
![4](https://user-images.githubusercontent.com/15846947/130355640-57690aa0-199d-4525-90ae-b7ed345dc228.png)
56+
57+
- How auth-requests verification is done
58+
59+
<img width="1407" alt="Screenshot 2021-08-22 at 6 15 28 PM" src="https://user-images.githubusercontent.com/15846947/130355747-96bf023e-cc02-4510-8fd5-129fb97e7aa6.png">
4360

44-
- Acknowledgment that the details are stored
45-
![3](https://user-images.githubusercontent.com/15846947/127329361-2b7d2e96-4a13-4245-b0db-1c6ead685195.jpeg)
4661

4762
- Behaviour post logging out from google/gmail or from the session
48-
cannot show logging out from gmail for personal reasons obviously :D
49-
50-
-![logout](https://user-images.githubusercontent.com/15846947/128707098-0c98a932-0bb9-4a51-ab6d-9d372677dc67.png)
51-
-![5](https://user-images.githubusercontent.com/15846947/127329414-3f56d681-28b2-47a4-9277-eba437d419d5.jpeg)
63+
64+
65+
![6](https://user-images.githubusercontent.com/15846947/130355653-12c2a454-dd82-499f-90a9-18f0297ff8e1.png)
66+
![7](https://user-images.githubusercontent.com/15846947/130355661-36264201-8e34-4979-9e72-932feeb77b0c.png)

authenticator/adapters/db/api.py

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
from flask_pymongo import PyMongo
1+
from pymongo import MongoClient
22
from flask import jsonify
33

4+
from authenticator.utils import utils
5+
46

57
class MongoAdapters(object):
6-
def __init__(self, app):
7-
self.client = PyMongo(app)
8-
self.db = self.client.db["authenticator"]
8+
def __init__(self, host, port):
9+
self.client = MongoClient(host, int(port))
10+
self.db = self.client["authenticator"]
911

1012
def get_all_users(self):
1113
collection = self.client.db["users"]
@@ -14,6 +16,15 @@ def get_all_users(self):
1416
output.append({"name": user["name"], "email": user["email"]})
1517
return jsonify({"result": output})
1618

19+
def is_valid_user(self, token):
20+
if self.db["users"].count_documents({"auth_token": token}) == 1:
21+
data = self.db["users"].find_one({"auth_token": token})
22+
if utils.check_user_longevity(data["expiration_time"]):
23+
response = {"name": data["name"], "email": data["email"]}
24+
return response
25+
else:
26+
return False
27+
1728
def add_users(
1829
self,
1930
name,
@@ -23,21 +34,22 @@ def add_users(
2334
provider=None,
2435
provider_id=None,
2536
):
26-
try:
27-
collection = self.client.db["users"]
28-
count = collection.count_documents({"email": email})
29-
if count == 0:
30-
collection_id = collection.insert(
31-
{
32-
"name": name,
33-
"email": email,
34-
"provider": provider,
35-
"provider_id": provider_id,
36-
"creation_time": creation_time,
37-
"user_type": user_type,
38-
}
39-
)
40-
return jsonify({"result": str(collection_id)})
41-
return jsonify({"token": "User already signed up"})
42-
except Exception:
43-
print("ISSUE")
37+
collection = self.db["users"]
38+
auth_token = utils.generate_auth_token()
39+
count = collection.count_documents({"email": email})
40+
if count == 0:
41+
collection_id = collection.insert(
42+
{
43+
"name": name,
44+
"email": email,
45+
"provider": provider,
46+
"provider_id": provider_id,
47+
"creation_time": creation_time,
48+
"user_type": user_type,
49+
"expiration_time": utils.get_expiration_time(creation_time),
50+
"auth_token": auth_token,
51+
}
52+
)
53+
return jsonify({"result": str(auth_token)})
54+
else:
55+
return jsonify({"result": "User already signed up"})

authenticator/adapters/login/google_adapter.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def __init__(self):
1414
self.flow = Flow.from_client_secrets_file(
1515
client_secrets_file=self.google_obj["secrets_file"],
1616
scopes=self.google_obj["scopes"],
17-
redirect_uri="http://127.0.0.1:5000/callback",
17+
redirect_uri=self.google_obj["redirect_uri"],
1818
)
1919

2020
def get_basic_info(self, request, session):

authenticator/app.py

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
import os
2-
import requests
2+
import oauthlib
33

44
from flask import Flask, session, url_for, abort, redirect, request
55

66
from authenticator.adapters.db import api as db_api
77
from authenticator.adapters.login import google_adapter
88
from authenticator.utils import utils
99

10-
database = os.environ.get("db", "authenticator")
10+
11+
app = Flask(__name__)
12+
1113
host = os.environ.get("db_host", "mongo")
1214
port = os.environ.get("db_port", "27017")
1315

14-
app = Flask(__name__)
15-
app.config["MONGO_URI"] = f"mongodb://{host}:{port}/{database}"
1616
app.config["SECRET_KEY"] = "b9dd1b2f"
1717
os.environ["OAUTHLIB_INSECURE_TRANSPORT"] = "1"
1818
app.config["GOOGLE_CLIENT_ID"] = os.environ.get("GOOGLE_CLIENT_ID", None)
1919
app.config["GOOGLE_CLIENT_SECRET"] = os.environ.get("GOOGLE_CLIENT_SECRET", None)
2020

2121

22-
db_obj = db_api.MongoAdapters(app)
22+
db_obj = db_api.MongoAdapters(host, port)
2323
google_adapter_obj = google_adapter.GoogleLoginAdapter()
2424

2525

@@ -33,11 +33,6 @@ def wrapper(*args, **kwargs):
3333
return wrapper
3434

3535

36-
@app.route("/users", methods=["GET"])
37-
def get_users():
38-
return db_obj.get_all_users()
39-
40-
4136
@app.route("/")
4237
def index():
4338
return "Hello World <a href='/googlelogin'><button>Sign Up with google</button></a>"
@@ -46,10 +41,20 @@ def index():
4641
def add_users(name, email, provider=None, provider_id=None):
4742
if email == "[email protected]":
4843
return db_obj.add_users(
49-
name, email, utils.get_current_time(), "admin", provider, provider_id
44+
name,
45+
email,
46+
utils.get_current_time(),
47+
"admin",
48+
provider,
49+
provider_id,
5050
)
5151
return db_obj.add_users(
52-
name, email, utils.get_current_time(), "user", provider=None, provider_id=None
52+
name,
53+
email,
54+
utils.get_current_time(),
55+
"user",
56+
provider,
57+
provider_id,
5358
)
5459

5560

@@ -60,20 +65,34 @@ def login():
6065
return redirect(authorization_url)
6166

6267

63-
@app.route("/callback")
64-
def callback():
65-
id_info = google_adapter_obj.get_basic_info(request, session)
68+
@app.route("/googlecallback")
69+
def googlecallback():
70+
try:
71+
id_info = google_adapter_obj.get_basic_info(request, session)
72+
except oauthlib.oauth2.rfc6749.errors.InvalidGrantError:
73+
return redirect("/")
74+
6675
if not session["state"] == request.args["state"]:
6776
abort(500) # State does not match!
6877

6978
name = id_info.get("name")
7079
email = id_info.get("email")
7180
google_id = id_info.get("sub")
81+
7282
session["google_id"] = google_id
7383
session["name"] = name
7484
session["email"] = email
75-
add_users(name, email, "google", google_id)
76-
return redirect("/protected_area")
85+
return add_users(name, email, "google", google_id)
86+
87+
88+
@app.route("/fetch", methods=["GET"])
89+
def validate_users():
90+
token = request.args.get("token")
91+
result = db_obj.is_valid_user(token)
92+
if isinstance(result, dict):
93+
return result
94+
else:
95+
abort(401, "unauthorized")
7796

7897

7998
@app.route("/logout")

authenticator/utils/utils.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,31 @@
11
import json
22
import time
3+
import uuid
34

45

56
def get_current_time():
67
return int(time.time()) * 1000
78

89

10+
def generate_auth_token():
11+
return str(uuid.uuid4()).split("-")[0]
12+
13+
914
def read_config():
1015
with open("config.json") as fp:
1116
data = json.load(fp)
1217
return data
18+
19+
20+
def get_expiration_time(creation_time):
21+
with open("config.json") as fp:
22+
data = json.load(fp)
23+
expiration_time = int(data["default"]["expiration_time"])
24+
return creation_time + expiration_time
25+
26+
27+
def check_user_longevity(expiration_time):
28+
if expiration_time <= int(time.time()) * 1000:
29+
return False
30+
else:
31+
return True

client_secret.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"web":{"client_id":"1034883885605-gvj78f1cg3urngprb0jjfr3p0olqh8tr.apps.googleusercontent.com","project_id":"horizontal-cab-234208","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"jPbO8Hxm20DkefDqmD4EyhCs","redirect_uris":["http://127.0.0.1:5000/login/google/authorize","http://127.0.0.1:7000/token", "http://127.0.0.1:5000/callback"],"javascript_origins":["http://127.0.0.1:5000","http://127.0.0.1:7000"]}}
1+
{"web":{"client_id":"1034883885605-gvj78f1cg3urngprb0jjfr3p0olqh8tr.apps.googleusercontent.com","project_id":"horizontal-cab-234208","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"jPbO8Hxm20DkefDqmD4EyhCs","redirect_uris":["http://127.0.0.1:5000/login/google/authorize","http://127.0.0.1:7000/token","http://127.0.0.1:5000/googlecallback"],"javascript_origins":["http://127.0.0.1:5000","http://127.0.0.1:7000"]}}

config.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,16 @@
66
"api_base_url":"https://www.googleapis.com/oauth2/v1/",
77
"userinfo_endpoint":"https://openidconnect.googleapis.com/v1/userinfo",
88
"secrets_file": "client_secret.json",
9-
"redirect_uri": "http://127.0.0.1:5000/callback",
9+
"redirect_uri": "http://127.0.0.1:5000/googlecallback",
1010
"google_client_id": "1034883885605-gvj78f1cg3urngprb0jjfr3p0olqh8tr.apps.googleusercontent.com",
1111
"scopes": [
1212
"https://www.googleapis.com/auth/userinfo.profile",
1313
"https://www.googleapis.com/auth/userinfo.email",
1414
"openid"
1515
]
1616
}
17+
},
18+
"default":{
19+
"expiration_time":"15768000000"
1720
}
1821
}

docker-compose.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ version: "3.7"
33
services:
44
authenticator:
55
image: authenticator_service_dev
6+
restart: always
67
volumes:
78
- ./:/app
89
build: .

0 commit comments

Comments
 (0)