diff --git a/auth-domain/user-manager/manage.py b/auth-domain/user-manager/manage.py index 9f5ee0f..782c64a 100644 --- a/auth-domain/user-manager/manage.py +++ b/auth-domain/user-manager/manage.py @@ -1,7 +1,7 @@ from flask.cli import FlaskGroup from src import create_app, db -from src.api.models.users import User +from src.api.models.users import Roles, User app = create_app() cli = FlaskGroup(create_app=create_app) @@ -21,7 +21,7 @@ def seed_db(): username="lufthansa", email="info@lufthansa.com", password="password1234", - airline=True, + role=Roles.airline, ) ) db.session.add( @@ -29,7 +29,15 @@ def seed_db(): username="ryanair", email="info@ryanair.com", password="password1234", - airline=True, + role=Roles.airline, + ) + ) + db.session.add( + User( + username="admin", + email="admin", + password="password1234", + role=Roles.admin, ) ) db.session.add( diff --git a/auth-domain/user-manager/src/api/auth.py b/auth-domain/user-manager/src/api/auth.py index a33575a..017ded9 100644 --- a/auth-domain/user-manager/src/api/auth.py +++ b/auth-domain/user-manager/src/api/auth.py @@ -34,7 +34,7 @@ class Login(Resource): if not user or not bcrypt.check_password_hash(user.password, password): auth_namespace.abort(404, "User does not exist") - access_token = user.encode_token(user.id, "access", user.airline) + access_token = user.encode_token(user.id, "access", user.role) refresh_token = user.encode_token(user.id, "refresh") response_object = { @@ -62,7 +62,7 @@ class Refresh(Resource): if not user: auth_namespace.abort(401, "Invalid token") - access_token = user.encode_token(user.id, "access", user.airline) + access_token = user.encode_token(user.id, "access", user.role) refresh_token = user.encode_token(user.id, "refresh") response_object = { diff --git a/auth-domain/user-manager/src/api/models/users.py b/auth-domain/user-manager/src/api/models/users.py index 992d775..1205617 100644 --- a/auth-domain/user-manager/src/api/models/users.py +++ b/auth-domain/user-manager/src/api/models/users.py @@ -1,4 +1,5 @@ import datetime +from enum import Enum import jwt from flask import current_app @@ -8,6 +9,12 @@ from sqlalchemy.sql import func from src import bcrypt, db +class Roles(Enum): + user = "user" + airline = "airline" + admin = "admin" + + class User(db.Model): __tablename__ = "users" @@ -17,18 +24,18 @@ class User(db.Model): password = db.Column(db.String(255), nullable=False) active = db.Column(db.Boolean(), default=True, nullable=False) created_date = db.Column(db.DateTime, default=func.now(), nullable=False) - airline = db.Column(db.Boolean(), default=False, nullable=False) + role = db.Column(db.String(128), default=Roles.user.value, nullable=False) - def __init__(self, username, email, password, airline=False): + def __init__(self, username, email, password, role=Roles.user): self.username = username self.email = email self.password = bcrypt.generate_password_hash( password, current_app.config.get("BCRYPT_LOG_ROUNDS") ).decode() - self.airline = airline + self.role = role.value @staticmethod - def encode_token(user_id, token_type, airline=False): + def encode_token(user_id, token_type, role="user"): if token_type == "access": seconds = current_app.config.get("ACCESS_TOKEN_EXPIRATION") else: @@ -38,7 +45,7 @@ class User(db.Model): "exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=seconds), "iat": datetime.datetime.utcnow(), "sub": user_id, - "airline": airline, + "role": role, } return jwt.encode( payload, current_app.config.get("SECRET_KEY"), algorithm="HS256" @@ -60,7 +67,7 @@ class User(db.Model): "username": fields.String(required=True), "email": fields.String(required=True), "created_date": fields.DateTime, - "airline": fields.Boolean(readOnly=True), + "role": fields.String(readOnly=True), }, ) @@ -91,7 +98,7 @@ class User(db.Model): "User", { "id": fields.Integer(required=True), - "airline": fields.Boolean(readOnly=True), + "role": fields.String(required=True), }, ) diff --git a/auth-domain/user-manager/src/api/users.py b/auth-domain/user-manager/src/api/users.py index 81e5566..05b927d 100644 --- a/auth-domain/user-manager/src/api/users.py +++ b/auth-domain/user-manager/src/api/users.py @@ -88,7 +88,7 @@ class Users(Resource): "username": user.username, "email": user.email, "created_date": user.created_date.strftime("%Y-%m-%d %H:%M:%S"), - "airline": user.airline, + "role": user.role, } return response_object, 200 diff --git a/auth-domain/user-manager/src/tests/functional/test_auth.py b/auth-domain/user-manager/src/tests/functional/test_auth.py index 2f29906..096506a 100644 --- a/auth-domain/user-manager/src/tests/functional/test_auth.py +++ b/auth-domain/user-manager/src/tests/functional/test_auth.py @@ -110,7 +110,7 @@ def test_user_status(test_app, test_database, add_user): data = json.loads(resp.data.decode()) assert resp.status_code == 200 assert resp.content_type == "application/json" - assert data["role"] == 0 + assert data["role"] == "user" assert "password" not in data diff --git a/auth-domain/user-manager/src/tests/unit/test_users.py b/auth-domain/user-manager/src/tests/unit/test_users.py index 5baffc9..5465894 100644 --- a/auth-domain/user-manager/src/tests/unit/test_users.py +++ b/auth-domain/user-manager/src/tests/unit/test_users.py @@ -190,7 +190,7 @@ def test_update_user(test_app, monkeypatch): "username": username, "email": email, "created_date": datetime.now(), - "airline": False, + "role": "user", } ) return d diff --git a/browser-domain/src/Types.d.ts b/browser-domain/src/Types.d.ts index 81b8ce7..574d4c3 100644 --- a/browser-domain/src/Types.d.ts +++ b/browser-domain/src/Types.d.ts @@ -11,7 +11,7 @@ export interface Token { export interface TokenData { sub: string; - airline: boolean; + role: string; } export interface User { diff --git a/browser-domain/src/useAuth.tsx b/browser-domain/src/useAuth.tsx index 9d8e993..4415a47 100644 --- a/browser-domain/src/useAuth.tsx +++ b/browser-domain/src/useAuth.tsx @@ -30,6 +30,7 @@ export function AuthProvider({ const [loading, setLoading] = useState(false); const [loadingInitial, setLoadingInitial] = useState(true); const [isAirline, setIsAirline] = useState(false); + const [isAdmin, setIsAdmin] = useState(false); const navigate = useNavigate(); useEffect(() => { @@ -39,10 +40,11 @@ export function AuthProvider({ useEffect(() => { const existingToken = localStorage.getItem("token"); if (existingToken) { - let airline + let role try { - airline = (jwt_decode(existingToken) as TokenData).airline; - setIsAirline(airline) + role = (jwt_decode(existingToken) as TokenData).role; + setIsAirline(role == "airline") + setIsAdmin(role == "admin") } catch (err) { setLoadingInitial(false); logout() @@ -73,8 +75,9 @@ export function AuthProvider({ const tokens = logIn(credentials) .then((x) => { localStorage.setItem("token", x.access_token); - const airline = (jwt_decode(x.access_token) as TokenData).airline; - setIsAirline(airline) + const role = (jwt_decode(x.access_token) as TokenData).role; + setIsAirline(role == "airline") + setIsAdmin(role == "admin") const user = fetchUserById(x.user_id as number, x.access_token) .then(y => { setUser(y); diff --git a/gateway/src/api/routes/auth.py b/gateway/src/api/routes/auth.py index b404917..782f457 100644 --- a/gateway/src/api/routes/auth.py +++ b/gateway/src/api/routes/auth.py @@ -55,7 +55,7 @@ async def checkAuth( ): response = await status(req, authorization) if isAirline: - if response["role"] == 1: + if response["role"] == "airline": return response["id"] else: raise HTTPException( diff --git a/gateway/src/api/schemas/user.py b/gateway/src/api/schemas/user.py index 8f49615..daee193 100644 --- a/gateway/src/api/schemas/user.py +++ b/gateway/src/api/schemas/user.py @@ -6,7 +6,7 @@ class User(BaseModel): username: str email: str created_date: str - airline: bool + role: str class UserMin(BaseModel): @@ -17,7 +17,7 @@ class UserMin(BaseModel): class UserStatus(BaseModel): id: int - airline: bool + role: str class UserRegister(BaseModel):