Add role fields (user, airlie, admin)
This commit is contained in:
parent
1dee061e97
commit
e3a5874196
|
@ -1,7 +1,7 @@
|
||||||
from flask.cli import FlaskGroup
|
from flask.cli import FlaskGroup
|
||||||
|
|
||||||
from src import create_app, db
|
from src import create_app, db
|
||||||
from src.api.models.users import User
|
from src.api.models.users import Roles, User
|
||||||
|
|
||||||
app = create_app()
|
app = create_app()
|
||||||
cli = FlaskGroup(create_app=create_app)
|
cli = FlaskGroup(create_app=create_app)
|
||||||
|
@ -21,7 +21,7 @@ def seed_db():
|
||||||
username="lufthansa",
|
username="lufthansa",
|
||||||
email="info@lufthansa.com",
|
email="info@lufthansa.com",
|
||||||
password="password1234",
|
password="password1234",
|
||||||
airline=True,
|
role=Roles.airline,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
db.session.add(
|
db.session.add(
|
||||||
|
@ -29,7 +29,15 @@ def seed_db():
|
||||||
username="ryanair",
|
username="ryanair",
|
||||||
email="info@ryanair.com",
|
email="info@ryanair.com",
|
||||||
password="password1234",
|
password="password1234",
|
||||||
airline=True,
|
role=Roles.airline,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
db.session.add(
|
||||||
|
User(
|
||||||
|
username="admin",
|
||||||
|
email="admin",
|
||||||
|
password="password1234",
|
||||||
|
role=Roles.admin,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
db.session.add(
|
db.session.add(
|
||||||
|
|
|
@ -34,7 +34,7 @@ class Login(Resource):
|
||||||
if not user or not bcrypt.check_password_hash(user.password, password):
|
if not user or not bcrypt.check_password_hash(user.password, password):
|
||||||
auth_namespace.abort(404, "User does not exist")
|
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")
|
refresh_token = user.encode_token(user.id, "refresh")
|
||||||
|
|
||||||
response_object = {
|
response_object = {
|
||||||
|
@ -62,7 +62,7 @@ class Refresh(Resource):
|
||||||
if not user:
|
if not user:
|
||||||
auth_namespace.abort(401, "Invalid token")
|
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")
|
refresh_token = user.encode_token(user.id, "refresh")
|
||||||
|
|
||||||
response_object = {
|
response_object = {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
import jwt
|
import jwt
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
@ -8,6 +9,12 @@ from sqlalchemy.sql import func
|
||||||
from src import bcrypt, db
|
from src import bcrypt, db
|
||||||
|
|
||||||
|
|
||||||
|
class Roles(Enum):
|
||||||
|
user = "user"
|
||||||
|
airline = "airline"
|
||||||
|
admin = "admin"
|
||||||
|
|
||||||
|
|
||||||
class User(db.Model):
|
class User(db.Model):
|
||||||
__tablename__ = "users"
|
__tablename__ = "users"
|
||||||
|
|
||||||
|
@ -17,18 +24,18 @@ class User(db.Model):
|
||||||
password = db.Column(db.String(255), nullable=False)
|
password = db.Column(db.String(255), nullable=False)
|
||||||
active = db.Column(db.Boolean(), default=True, nullable=False)
|
active = db.Column(db.Boolean(), default=True, nullable=False)
|
||||||
created_date = db.Column(db.DateTime, default=func.now(), 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.username = username
|
||||||
self.email = email
|
self.email = email
|
||||||
self.password = bcrypt.generate_password_hash(
|
self.password = bcrypt.generate_password_hash(
|
||||||
password, current_app.config.get("BCRYPT_LOG_ROUNDS")
|
password, current_app.config.get("BCRYPT_LOG_ROUNDS")
|
||||||
).decode()
|
).decode()
|
||||||
self.airline = airline
|
self.role = role.value
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def encode_token(user_id, token_type, airline=False):
|
def encode_token(user_id, token_type, role="user"):
|
||||||
if token_type == "access":
|
if token_type == "access":
|
||||||
seconds = current_app.config.get("ACCESS_TOKEN_EXPIRATION")
|
seconds = current_app.config.get("ACCESS_TOKEN_EXPIRATION")
|
||||||
else:
|
else:
|
||||||
|
@ -38,7 +45,7 @@ class User(db.Model):
|
||||||
"exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=seconds),
|
"exp": datetime.datetime.utcnow() + datetime.timedelta(seconds=seconds),
|
||||||
"iat": datetime.datetime.utcnow(),
|
"iat": datetime.datetime.utcnow(),
|
||||||
"sub": user_id,
|
"sub": user_id,
|
||||||
"airline": airline,
|
"role": role,
|
||||||
}
|
}
|
||||||
return jwt.encode(
|
return jwt.encode(
|
||||||
payload, current_app.config.get("SECRET_KEY"), algorithm="HS256"
|
payload, current_app.config.get("SECRET_KEY"), algorithm="HS256"
|
||||||
|
@ -60,7 +67,7 @@ class User(db.Model):
|
||||||
"username": fields.String(required=True),
|
"username": fields.String(required=True),
|
||||||
"email": fields.String(required=True),
|
"email": fields.String(required=True),
|
||||||
"created_date": fields.DateTime,
|
"created_date": fields.DateTime,
|
||||||
"airline": fields.Boolean(readOnly=True),
|
"role": fields.String(readOnly=True),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -91,7 +98,7 @@ class User(db.Model):
|
||||||
"User",
|
"User",
|
||||||
{
|
{
|
||||||
"id": fields.Integer(required=True),
|
"id": fields.Integer(required=True),
|
||||||
"airline": fields.Boolean(readOnly=True),
|
"role": fields.String(required=True),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ class Users(Resource):
|
||||||
"username": user.username,
|
"username": user.username,
|
||||||
"email": user.email,
|
"email": user.email,
|
||||||
"created_date": user.created_date.strftime("%Y-%m-%d %H:%M:%S"),
|
"created_date": user.created_date.strftime("%Y-%m-%d %H:%M:%S"),
|
||||||
"airline": user.airline,
|
"role": user.role,
|
||||||
}
|
}
|
||||||
return response_object, 200
|
return response_object, 200
|
||||||
|
|
||||||
|
|
|
@ -110,7 +110,7 @@ def test_user_status(test_app, test_database, add_user):
|
||||||
data = json.loads(resp.data.decode())
|
data = json.loads(resp.data.decode())
|
||||||
assert resp.status_code == 200
|
assert resp.status_code == 200
|
||||||
assert resp.content_type == "application/json"
|
assert resp.content_type == "application/json"
|
||||||
assert data["role"] == 0
|
assert data["role"] == "user"
|
||||||
assert "password" not in data
|
assert "password" not in data
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -190,7 +190,7 @@ def test_update_user(test_app, monkeypatch):
|
||||||
"username": username,
|
"username": username,
|
||||||
"email": email,
|
"email": email,
|
||||||
"created_date": datetime.now(),
|
"created_date": datetime.now(),
|
||||||
"airline": False,
|
"role": "user",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return d
|
return d
|
||||||
|
|
|
@ -11,7 +11,7 @@ export interface Token {
|
||||||
|
|
||||||
export interface TokenData {
|
export interface TokenData {
|
||||||
sub: string;
|
sub: string;
|
||||||
airline: boolean;
|
role: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface User {
|
export interface User {
|
||||||
|
|
|
@ -30,6 +30,7 @@ export function AuthProvider({
|
||||||
const [loading, setLoading] = useState<boolean>(false);
|
const [loading, setLoading] = useState<boolean>(false);
|
||||||
const [loadingInitial, setLoadingInitial] = useState<boolean>(true);
|
const [loadingInitial, setLoadingInitial] = useState<boolean>(true);
|
||||||
const [isAirline, setIsAirline] = useState(false);
|
const [isAirline, setIsAirline] = useState(false);
|
||||||
|
const [isAdmin, setIsAdmin] = useState(false);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -39,10 +40,11 @@ export function AuthProvider({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const existingToken = localStorage.getItem("token");
|
const existingToken = localStorage.getItem("token");
|
||||||
if (existingToken) {
|
if (existingToken) {
|
||||||
let airline
|
let role
|
||||||
try {
|
try {
|
||||||
airline = (jwt_decode(existingToken) as TokenData).airline;
|
role = (jwt_decode(existingToken) as TokenData).role;
|
||||||
setIsAirline(airline)
|
setIsAirline(role == "airline")
|
||||||
|
setIsAdmin(role == "admin")
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setLoadingInitial(false);
|
setLoadingInitial(false);
|
||||||
logout()
|
logout()
|
||||||
|
@ -73,8 +75,9 @@ export function AuthProvider({
|
||||||
const tokens = logIn(credentials)
|
const tokens = logIn(credentials)
|
||||||
.then((x) => {
|
.then((x) => {
|
||||||
localStorage.setItem("token", x.access_token);
|
localStorage.setItem("token", x.access_token);
|
||||||
const airline = (jwt_decode(x.access_token) as TokenData).airline;
|
const role = (jwt_decode(x.access_token) as TokenData).role;
|
||||||
setIsAirline(airline)
|
setIsAirline(role == "airline")
|
||||||
|
setIsAdmin(role == "admin")
|
||||||
const user = fetchUserById(x.user_id as number, x.access_token)
|
const user = fetchUserById(x.user_id as number, x.access_token)
|
||||||
.then(y => {
|
.then(y => {
|
||||||
setUser(y);
|
setUser(y);
|
||||||
|
|
|
@ -55,7 +55,7 @@ async def checkAuth(
|
||||||
):
|
):
|
||||||
response = await status(req, authorization)
|
response = await status(req, authorization)
|
||||||
if isAirline:
|
if isAirline:
|
||||||
if response["role"] == 1:
|
if response["role"] == "airline":
|
||||||
return response["id"]
|
return response["id"]
|
||||||
else:
|
else:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
|
|
|
@ -6,7 +6,7 @@ class User(BaseModel):
|
||||||
username: str
|
username: str
|
||||||
email: str
|
email: str
|
||||||
created_date: str
|
created_date: str
|
||||||
airline: bool
|
role: str
|
||||||
|
|
||||||
|
|
||||||
class UserMin(BaseModel):
|
class UserMin(BaseModel):
|
||||||
|
@ -17,7 +17,7 @@ class UserMin(BaseModel):
|
||||||
|
|
||||||
class UserStatus(BaseModel):
|
class UserStatus(BaseModel):
|
||||||
id: int
|
id: int
|
||||||
airline: bool
|
role: str
|
||||||
|
|
||||||
|
|
||||||
class UserRegister(BaseModel):
|
class UserRegister(BaseModel):
|
||||||
|
|
Loading…
Reference in New Issue