Skip to content

Commit 99b9b6d

Browse files
authored
Merge pull request #60 from ProgrammingBuddies/login
Login
2 parents 4f8ad8c + 247b261 commit 99b9b6d

File tree

8 files changed

+126
-119
lines changed

8 files changed

+126
-119
lines changed

Pipfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ mysql-connector-python = "*"
1414
flask-dance = "*"
1515
pyopenssl = "*"
1616
flask-cors = "*"
17-
flask-login = "*"
1817
blinker = "*"
18+
flask-jwt-extended = "*"
1919

2020
[requires]
2121
python_version = "3.7"

Pipfile.lock

Lines changed: 31 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Run the server:
3535
- Under your GitHub account Settings go to Developer settings and OAuth Apps
3636
- Create a new one and set the homepage url to `https://localhost:5001/` and Authorization callback to `https://localhost:5001/login/github/authorized`
3737
- Copy the Client Id and Client Secret from that site and save them in `.env` as `GITHUB_ID` and `GITHUB_SECRET` respectively
38+
4. Furthermore a `JWT_SECRET_KEY` is required for signing the JWT-tokens
3839

3940
Your `.env` file should now look something like [example.env](https://github.com/ProgrammingBuddies/programmingbuddies-api/blob/develop/example.env)
4041

example.env

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ CONNECT=mysql+mysqlconnector://user:password@localhost:3306/meintest
22
FLASK_ENV=development
33
APP_SECRET=guest
44
GITHUB_ID=c1fed8b3f0e10e0beef
5-
GITHUB_SECRET=de79b512d6fbeefa9cdc113beef219ccc7cd98f1
5+
GITHUB_SECRET=de79b512d6fbeefa9cdc113beef219ccc7cd98f1
6+
JWT_SECRET_KEY=guest

src/api/controllers/userController.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
from api.models import db, User, UserHasProject, UserLink
2-
from flask_login import LoginManager
32
from api import app
43

54
class UserController:
65
session = db.session()
76

8-
login_manager = LoginManager()
9-
login_manager.init_app(app)
10-
117
def create_user(self, **kwargs):
128
user = User(**kwargs)
139
self.session.add(user)
@@ -28,7 +24,6 @@ def update_user(self, id, **kwargs):
2824

2925
return user
3026

31-
@login_manager.user_loader
3227
def get_user(self, **kwargs):
3328
user = User.query.filter_by(**kwargs).first()
3429

src/api/models/userModel.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
from api.models.userHasProjectModel import UserHasProject
44
from api.models.userLinkModel import UserLink
55

6-
from flask_login import UserMixin
7-
8-
class User(UserMixin, db.Model):
6+
class User(db.Model):
97
id = db.Column(db.Integer, primary_key=True)
108
github_id = db.Column(db.Integer)
119
name = db.Column(db.String(80), nullable=False)

src/api/views/oauthView.py

Lines changed: 90 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,90 @@
1-
# from api import app
2-
# from os import environ
3-
# from flask import Flask, request, redirect, session, url_for
4-
# from flask_dance.contrib.github import make_github_blueprint, github
5-
6-
# print("hello")
7-
# app.secret_key = environ.get("APP_SECRET")
8-
# github_blueprint = make_github_blueprint(
9-
# client_id = environ.get("GITHUB_ID"),
10-
# client_secret = environ.get("GITHUB_SECRET")
11-
# )
12-
13-
# app.register_blueprint(github_blueprint, url_prefix="/login")
14-
15-
# @app.route("/login/")
16-
# def index():
17-
# if not github.authorized:
18-
# return redirect(url_for("github.login"))
19-
# resp = github.get("/user")
20-
# uid = resp.json()["id"]
21-
# print(uid)
22-
# return "You are @{login} on GitHub".format(login=resp.json()["login"])
1+
from flask_jwt_extended import JWTManager, jwt_required, get_jwt_identity, get_jwt_claims, create_access_token
2+
from api.models import User
3+
from flask import request, jsonify, session, Flask, redirect, session, url_for
4+
from api import app
5+
from os import environ
6+
from api.controllers import userController
7+
from flask_dance.contrib.github import make_github_blueprint, github
8+
from flask_dance.consumer import oauth_authorized
9+
10+
app.secret_key = environ.get("APP_SECRET")
11+
github_blueprint = make_github_blueprint(
12+
client_id = environ.get("GITHUB_ID"),
13+
client_secret = environ.get("GITHUB_SECRET")
14+
)
15+
16+
app.register_blueprint(github_blueprint, url_prefix="/login")
17+
18+
app.config['JWT_SECRET_KEY'] = environ.get("JWT_SECRET_KEY")
19+
jwt = JWTManager(app)
20+
21+
@jwt.user_identity_loader
22+
def user_identity_lookup(user):
23+
return user.id
24+
25+
@app.route("/login", methods=["GET"])
26+
def login_route():
27+
account = request.args.get('account')
28+
session['action'] = "login"
29+
session['redirect'] = request.args.get('redirect')
30+
session['state'] = request.args.get('state','{}')
31+
32+
if account == 'github':
33+
return redirect(url_for("github.login"))
34+
else:
35+
return "", 400
36+
37+
@app.route("/register", methods=["GET"])
38+
def register_route():
39+
account = request.args.get('account')
40+
session['action'] = "register"
41+
# TODO remove or not?
42+
session['username'] = request.args.get('username')
43+
session['redirect'] = request.args.get('redirect')
44+
session['state'] = request.args.get('state','{}')
45+
46+
if account == 'github':
47+
return redirect(url_for("github.login"))
48+
else:
49+
return "", 400
50+
51+
@oauth_authorized.connect
52+
def oathed(blueprint, token):
53+
if session['action'] == 'login':
54+
return login_callback(blueprint)
55+
elif session['action'] == 'register':
56+
return register_callback(blueprint)
57+
else:
58+
return "", 501
59+
60+
61+
def login_callback(blueprint):
62+
if blueprint.name == "github":
63+
resp = github.get("/user").json()
64+
id = resp["id"]
65+
user = userController.get_user(github_id=id)
66+
redirect_token = f"?state={session.pop('state', '{}')}"
67+
if user:
68+
access_token = create_access_token(identity=user)
69+
redirect_token += f"&token={access_token}"
70+
71+
return redirect(session.pop("redirect") + redirect_token)
72+
73+
def register_callback(blueprint):
74+
if blueprint.name == "github":
75+
resp = github.get("/user").json()
76+
id = resp["id"]
77+
user = userController.get_user(github_id=id)
78+
if not user:
79+
user = userController.create_user(github_id=id, name=session.pop('username', "Anton"))
80+
access_token = create_access_token(identity=user)
81+
redirect_token = f"?state={session.pop('state')}&token={access_token}"
82+
return redirect(session.pop('redirect') + redirect_token)
83+
84+
# Actually deprecated
85+
# should be /user in userview but I'll leave it until Routes branch adds and merges it
86+
@app.route("/getcurrentuser", methods=["GET"])
87+
@jwt_required
88+
def getCurrentUser():
89+
current_user = userController.get_user(id=get_jwt_identity())
90+
return jsonify(current_user.as_dict()), 200

0 commit comments

Comments
 (0)