introduce admin area
introduce admin area first poc for connecting the authentik api Co-authored-by: Philipp Rothmann <philipprothmann@posteo.de> Reviewed-on: #2
This commit is contained in:
parent
8d760e588f
commit
44e4e4eb42
35 changed files with 367 additions and 133 deletions
|
|
@ -1,32 +0,0 @@
|
|||
"""Everything to do with Apps"""
|
||||
|
||||
from database import db
|
||||
from .models import App
|
||||
|
||||
class LITApp(App):
|
||||
"""
|
||||
"""
|
||||
|
||||
def get_url(self):
|
||||
return self.url
|
||||
|
||||
def to_dict(self):
|
||||
"""
|
||||
represent this object as a dict, compatible for JSON output
|
||||
"""
|
||||
return {"id": self.id,
|
||||
"name": self.name,
|
||||
"slug": self.slug,
|
||||
"external": self.external,
|
||||
"status": self.get_status(),
|
||||
"url": self.get_url()}
|
||||
|
||||
|
||||
|
||||
def get_status(self):
|
||||
"""Returns an AppStatus object that describes the current cluster state"""
|
||||
return {
|
||||
"installed": "",
|
||||
"ready": "",
|
||||
"message": "",
|
||||
}
|
||||
|
|
@ -5,15 +5,14 @@ from flask_cors import cross_origin
|
|||
from datetime import timedelta
|
||||
|
||||
from areas import api_v1
|
||||
from areas.apps import App, AppRole
|
||||
from config import *
|
||||
from helpers import HydraOauth, BadRequest
|
||||
from helpers import LITOauth, BadRequest
|
||||
|
||||
|
||||
@api_v1.route("/login", methods=["POST"])
|
||||
@cross_origin()
|
||||
def login():
|
||||
authorization_url = HydraOauth.authorize()
|
||||
authorization_url = LITOauth.authorize()
|
||||
return jsonify({"authorizationUrl": authorization_url})
|
||||
|
||||
|
||||
|
|
@ -28,26 +27,17 @@ def hydra_callback():
|
|||
if code == None:
|
||||
raise BadRequest("Missing code query param")
|
||||
|
||||
token = HydraOauth.get_token(state, code)
|
||||
user_info = HydraOauth.get_user_info()
|
||||
|
||||
token = LITOauth.get_token(state, code)
|
||||
user_info = LITOauth.get_user_info()
|
||||
access_token = create_access_token(
|
||||
identity=token, expires_delta=timedelta(days=365),
|
||||
#additional_claims={"user_id": identity["id"]}
|
||||
)
|
||||
|
||||
# apps = App.query.all()
|
||||
# app_roles = []
|
||||
# for app in apps:
|
||||
# tmp_app_role = AppRole.query.filter_by(
|
||||
# user_id=identity["id"], app_id=app.id
|
||||
# ).first()
|
||||
# app_roles.append(
|
||||
# {
|
||||
# "name": app.slug,
|
||||
# "role_id": tmp_app_role.role_id if tmp_app_role else None,
|
||||
# }
|
||||
# )
|
||||
identity=token, expires_delta=timedelta(days=365))
|
||||
isAdmin = "admin" in user_info["groups"]
|
||||
app_roles = [
|
||||
{
|
||||
"name": "dashboard",
|
||||
"role_id": 1 if isAdmin else 2
|
||||
},
|
||||
]
|
||||
|
||||
return jsonify(
|
||||
{
|
||||
|
|
@ -57,7 +47,7 @@ def hydra_callback():
|
|||
"email": user_info["email"],
|
||||
"name": user_info["name"],
|
||||
"preferredUsername": user_info["preferred_username"],
|
||||
# "app_roles": app_roles,
|
||||
},
|
||||
"app_roles": app_roles
|
||||
}
|
||||
}
|
||||
)
|
||||
|
|
|
|||
39
backend/areas/users/lit_user_service.py
Normal file
39
backend/areas/users/lit_user_service.py
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
from flask import current_app
|
||||
from helpers.authentik_api import AuthentikApi
|
||||
from .user_service import UserService
|
||||
from .models import User
|
||||
|
||||
|
||||
class UserService(UserService):
|
||||
@staticmethod
|
||||
def get_users():
|
||||
user_list = [User.from_authentik(u).to_dict() for u in AuthentikApi.get("/core/users")]
|
||||
return user_list
|
||||
|
||||
@staticmethod
|
||||
def get_user(id):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def post_user(data):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def __start_recovery_flow(email):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def put_user(id, user_editing_id, data):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def delete_user(id):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def post_multiple_users(data):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def __insertAppRoleToUser(userId, userRes):
|
||||
pass
|
||||
37
backend/areas/users/models.py
Normal file
37
backend/areas/users/models.py
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
|
||||
class User:
|
||||
id = None
|
||||
uuid = None
|
||||
traits = None
|
||||
email = None
|
||||
name = None
|
||||
preferredUsername = None
|
||||
state = None
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def from_authentik(authentik_user):
|
||||
u = User()
|
||||
u.id = authentik_user["pk"]
|
||||
u.uuid = authentik_user["uid"]
|
||||
u.name = authentik_user["name"]
|
||||
u.email = authentik_user["email"]
|
||||
u.traits = {
|
||||
"name": authentik_user["name"],
|
||||
"email": authentik_user["email"],
|
||||
"app_roles": []
|
||||
}
|
||||
u.preferredUsername = authentik_user["username"]
|
||||
u.state = "active" if authentik_user["is_active"] else ""
|
||||
return u
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"traits": self.traits,
|
||||
"preferredUsername": self.preferredUsername,
|
||||
"state": self.state,
|
||||
}
|
||||
|
|
@ -8,16 +8,15 @@ from helpers import KratosApi
|
|||
from helpers.auth_guard import admin_required
|
||||
|
||||
from .validation import schema, schema_multiple
|
||||
from .user_service import UserService
|
||||
from .lit_user_service import UserService
|
||||
|
||||
|
||||
@api_v1.route("/users", methods=["GET"])
|
||||
@jwt_required()
|
||||
@cross_origin()
|
||||
@admin_required()
|
||||
# @admin_required() TODO: not needed as authentik checks permissions?
|
||||
def get_users():
|
||||
res = UserService.get_users()
|
||||
return jsonify(res)
|
||||
return jsonify(UserService.get_users())
|
||||
|
||||
|
||||
@api_v1.route("/users/<string:id>", methods=["GET"])
|
||||
|
|
|
|||
Reference in a new issue