Skip to content

Commit

Permalink
Refactoring authentication and added profile information
Browse files Browse the repository at this point in the history
Moved login_required to auth module
Added method to retrieve user data
Added /profile/me endpoint with userdata
  • Loading branch information
simcax committed Jan 13, 2022
1 parent 0bd24c0 commit 2a79f40
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 18 deletions.
14 changes: 13 additions & 1 deletion app/auth/authentication.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'''Class for authentication'''
import functools
from psycopg2 import DatabaseError
from flask import current_app
from flask import current_app, redirect, url_for, g
from app.db import database

class Authentication:
Expand Down Expand Up @@ -32,3 +33,14 @@ def get_user_data(self,uuid):
finally:
conn.close()
return user

def login_required(view):
'''Force login for endpoints, which require it'''
@functools.wraps(view)
def wrapped_view(**kwargs):
if g.user is None:
return redirect(url_for('auth_blueprint.login'))

return view(**kwargs)

return wrapped_view
22 changes: 22 additions & 0 deletions app/profile/profile.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'''Class to handle new users'''
from werkzeug.security import check_password_hash, generate_password_hash
from psycopg2 import DatabaseError
from flask import current_app
from app.db.database import Database
class ProfileHandling:
'''Profile handling'''
Expand Down Expand Up @@ -84,3 +85,24 @@ def check_credentials(self,email,password):
finally:
conn.close()
return users_id

def get_user_data(self,user_id):
'''Retrieves a users profile data'''
return_value = False
try:
db_obj = Database()
conn = db_obj.connect()
with conn.cursor() as cur:
sql = f"SELECT username, email FROM soc.users \
WHERE usersid = '{user_id}'\
"
cur.execute(sql)
if cur.rowcount >= 1:
row = cur.fetchone()
userdata = { 'username': row[0], 'email': row[1]}
return_value = userdata
except DatabaseError as error:
current_app.logger.error("Problem running sql %s, error: %s", sql, error)
finally:
conn.close()
return return_value
17 changes: 4 additions & 13 deletions app/routes/auth_routes.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
'''Routes for auth/login to the application'''
import functools
from flask import (
Blueprint, render_template, request, flash, session, g, redirect, url_for, current_app
Blueprint, render_template, request, flash, session, g, current_app
)
from app.profile.profile import ProfileHandling

from app.auth.authentication import Authentication
from app.auth.authentication import Authentication, login_required


bp1 = Blueprint('auth_blueprint', __name__, url_prefix='/auth')

@bp1.route("/login", methods=["GET", "POST"])
Expand All @@ -29,16 +30,6 @@ def login():

return return_is

def login_required(view):
'''Force login for endpoints, which require it'''
@functools.wraps(view)
def wrapped_view(**kwargs):
if g.user is None:
return redirect(url_for('auth_blueprint.login'))

return view(**kwargs)

return wrapped_view

@bp1.route("/unauthorized")
@login_required
Expand Down
10 changes: 7 additions & 3 deletions app/routes/profile_routes.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
'''Routes for profile creation'''

from flask import Blueprint, render_template, request
from flask import Blueprint, render_template, request,session
from app.profile.profile import ProfileHandling

from app.auth.authentication import login_required
bp = Blueprint('profile_blueprint', __name__, url_prefix='/profile')

@bp.route("/create", methods=["GET", "POST"])
Expand All @@ -28,6 +28,10 @@ def profile_info():
return "This is the profile info endpoint"

@bp.route("/me")
@login_required
def profile():
'''Endpoint to show information about your own profile'''
return "Profile info"
prof = ProfileHandling()
users_id = session['user_id']
userdata = prof.get_user_data(users_id)
return render_template("profile_me.html", userdata=userdata)
34 changes: 34 additions & 0 deletions app/templates/profile_me.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{% extends "header.html" %}
{% block profile %}
<div class="container">
<br/><br/><br/>
<div class="card" style="width: 50rem;">
<div class="card-body">
<h5 class="card-title">Profile Information</h5>
<form action="createprofile" method="POST">
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control" id="username" placeholder="Username" name="profileUsername" value="{{ userdata['username'] }}">
</div>
<div class="form-row">
<div class="col">
<label for="email">Email address</label>
<input type="text" class="form-control" id="email" placeholder="Email" name="profileEmail" value="{{ userdata['email'] }}">
</div>
</div>
<div class="form-row">
<div class="col">

</div>
<div class="col">
<button type="submit" class="btn btn-success float-right" >Create Profile</button>
</div>
</div>
</form>
</div>
</div>
</div>
{% endblock %}



11 changes: 10 additions & 1 deletion test_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,13 @@ def test_cookie_flags_2(client, create_user):

def test_profile_endpoint(client):
rv = client.get("/profile/me")
assert rv.status_code == 200
assert rv.status_code == 302

def test_profile_endpoint_not_logged_in(client):
'''
Test we are being redirected to login when accessing the profile/me endpoint
when we are not logged in
'''
rv = client.get("/profile/me")
assert rv.location.endswith("/auth/login")

13 changes: 13 additions & 0 deletions test_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,16 @@ def test_check_password():
prof = ProfileHandling()
user_id = prof.check_credentials(email,password)
assert user_id != None

def test_retrieve_profile_data():
'''Test getting profile data'''
prof = ProfileHandling()
tu = TestUtils()
username = tu.createRandomString()
password = tu.createRandomString()
email = tu.createRandomEmail()
prof = ProfileHandling()
user_id = prof.add_user(username,password,email)
userdata = prof.get_user_data(user_id.get('users_id'))
assert username == userdata['username']
assert email == userdata['email']

0 comments on commit 2a79f40

Please sign in to comment.