mirror of
https://git.selfprivacy.org/SelfPrivacy/selfprivacy-rest-api.git
synced 2025-01-30 20:56:39 +00:00
fix: rename origin, add new mutation
This commit is contained in:
parent
b662d0f243
commit
ecb3f36f96
|
@ -0,0 +1 @@
|
||||||
|
PLEASE_UPDATE_APP_TEXT = "Your SelfPrivacy app is out of date, please update. Some important functions are not working at the moment."
|
|
@ -121,3 +121,10 @@ def get_user_by_username(username: str) -> Optional[UserDataUser]:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
def generate_password_reset_link(username: str) -> str:
|
||||||
|
if ACTIVE_USERS_PROVIDER == JsonUserRepository:
|
||||||
|
return "Error: API using old user manager provider!"
|
||||||
|
|
||||||
|
return ACTIVE_USERS_PROVIDER.generate_password_reset_link(username=username)
|
||||||
|
|
|
@ -23,12 +23,13 @@ class UserType(Enum):
|
||||||
@strawberry.type
|
@strawberry.type
|
||||||
class User:
|
class User:
|
||||||
username: str
|
username: str
|
||||||
user_type: UserType
|
|
||||||
|
ssh_keys: Optional[list[str]] = strawberry.field(default_factory=list)
|
||||||
|
user_type: Optional[UserType] = None
|
||||||
displayname: Optional[str] = None
|
displayname: Optional[str] = None
|
||||||
ssh_keys: list[str] = strawberry.field(default_factory=list)
|
|
||||||
email: Optional[str] = None
|
email: Optional[str] = None
|
||||||
directmemberof: Optional[list[str]] = strawberry.field(default_factory=list)
|
directmemberof: Optional[list[str]] = None
|
||||||
memberof: Optional[list[str]] = strawberry.field(default_factory=list)
|
memberof: Optional[list[str]] = None
|
||||||
# userHomeFolderspace: UserHomeFolderUsage
|
# userHomeFolderspace: UserHomeFolderUsage
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ class UserMutationReturn(MutationReturnInterface):
|
||||||
"""Return type for user mutation"""
|
"""Return type for user mutation"""
|
||||||
|
|
||||||
user: Optional[User] = None
|
user: Optional[User] = None
|
||||||
|
password_reset_link: Optional[str] = None
|
||||||
|
|
||||||
|
|
||||||
def get_user_by_username(username: str) -> Optional[User]:
|
def get_user_by_username(username: str) -> Optional[User]:
|
||||||
|
@ -45,13 +47,13 @@ def get_user_by_username(username: str) -> Optional[User]:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return User(
|
return User(
|
||||||
user_type=UserType(user.origin.value),
|
|
||||||
username=user.username,
|
username=user.username,
|
||||||
ssh_keys=user.ssh_keys,
|
ssh_keys=user.ssh_keys or [],
|
||||||
displayname=(user.displayname if user.displayname else user.username),
|
user_type=user.user_type or None,
|
||||||
email=user.email,
|
displayname=user.displayname or None,
|
||||||
directmemberof=user.directmemberof,
|
email=user.email or None,
|
||||||
memberof=user.memberof,
|
directmemberof=user.directmemberof or None,
|
||||||
|
memberof=user.memberof or None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -60,13 +62,13 @@ def get_users() -> list[User]:
|
||||||
users = actions_get_users(exclude_root=True)
|
users = actions_get_users(exclude_root=True)
|
||||||
return [
|
return [
|
||||||
User(
|
User(
|
||||||
user_type=UserType(user.origin.value),
|
|
||||||
username=user.username,
|
username=user.username,
|
||||||
ssh_keys=user.ssh_keys,
|
ssh_keys=user.ssh_keys or [],
|
||||||
displayname=(user.displayname if user.displayname else user.username),
|
user_type=user.user_type or None,
|
||||||
email=user.email,
|
displayname=user.displayname or None,
|
||||||
directmemberof=user.directmemberof,
|
email=user.email or None,
|
||||||
memberof=user.memberof,
|
directmemberof=user.directmemberof or None,
|
||||||
|
memberof=user.memberof or None,
|
||||||
)
|
)
|
||||||
for user in users
|
for user in users
|
||||||
]
|
]
|
||||||
|
|
|
@ -23,6 +23,7 @@ from selfprivacy_api.actions.users import (
|
||||||
create_user as create_user_action,
|
create_user as create_user_action,
|
||||||
delete_user as delete_user_action,
|
delete_user as delete_user_action,
|
||||||
update_user as update_user_action,
|
update_user as update_user_action,
|
||||||
|
generate_password_reset_link as generate_password_reset_link_action,
|
||||||
)
|
)
|
||||||
from selfprivacy_api.repositories.users.exceptions import (
|
from selfprivacy_api.repositories.users.exceptions import (
|
||||||
PasswordIsEmpty,
|
PasswordIsEmpty,
|
||||||
|
@ -33,7 +34,9 @@ from selfprivacy_api.repositories.users.exceptions import (
|
||||||
UsernameNotAlphanumeric,
|
UsernameNotAlphanumeric,
|
||||||
UsernameTooLong,
|
UsernameTooLong,
|
||||||
UserNotFound,
|
UserNotFound,
|
||||||
|
SelfPrivacyAppIsOutdate,
|
||||||
)
|
)
|
||||||
|
from selfprivacy_api import PLEASE_UPDATE_APP_TEXT
|
||||||
|
|
||||||
|
|
||||||
@strawberry.input
|
@strawberry.input
|
||||||
|
@ -44,8 +47,8 @@ class UserMutationInput:
|
||||||
password: Optional[str] = None
|
password: Optional[str] = None
|
||||||
displayname: Optional[str] = None
|
displayname: Optional[str] = None
|
||||||
email: Optional[str] = None
|
email: Optional[str] = None
|
||||||
directmemberof: Optional[list[str]] = strawberry.field(default_factory=list)
|
directmemberof: Optional[list[str]] = None
|
||||||
memberof: Optional[list[str]] = strawberry.field(default_factory=list)
|
memberof: Optional[list[str]] = None
|
||||||
|
|
||||||
|
|
||||||
@strawberry.input
|
@strawberry.input
|
||||||
|
@ -111,7 +114,7 @@ class UsersMutations:
|
||||||
|
|
||||||
return UserMutationReturn(
|
return UserMutationReturn(
|
||||||
success=True,
|
success=True,
|
||||||
message="User created",
|
message=PLEASE_UPDATE_APP_TEXT if user.password else "User created",
|
||||||
code=201,
|
code=201,
|
||||||
user=get_user_by_username(user.username),
|
user=get_user_by_username(user.username),
|
||||||
)
|
)
|
||||||
|
@ -163,6 +166,12 @@ class UsersMutations:
|
||||||
message=str(e),
|
message=str(e),
|
||||||
code=404,
|
code=404,
|
||||||
)
|
)
|
||||||
|
except SelfPrivacyAppIsOutdate:
|
||||||
|
return UserMutationReturn(
|
||||||
|
success=False,
|
||||||
|
message="Error: Failed to change password.", PLEASE_UPDATE_APP_TEXT,
|
||||||
|
code=400,
|
||||||
|
)
|
||||||
|
|
||||||
return UserMutationReturn(
|
return UserMutationReturn(
|
||||||
success=True,
|
success=True,
|
||||||
|
@ -195,7 +204,7 @@ class UsersMutations:
|
||||||
message="User not found",
|
message="User not found",
|
||||||
code=404,
|
code=404,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e: # TODO why?
|
||||||
return UserMutationReturn(
|
return UserMutationReturn(
|
||||||
success=False,
|
success=False,
|
||||||
message=str(e),
|
message=str(e),
|
||||||
|
@ -227,7 +236,7 @@ class UsersMutations:
|
||||||
message="User not found",
|
message="User not found",
|
||||||
code=404,
|
code=404,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e: # TODO why?
|
||||||
return UserMutationReturn(
|
return UserMutationReturn(
|
||||||
success=False,
|
success=False,
|
||||||
message=str(e),
|
message=str(e),
|
||||||
|
@ -240,3 +249,21 @@ class UsersMutations:
|
||||||
code=200,
|
code=200,
|
||||||
user=get_user_by_username(ssh_input.username),
|
user=get_user_by_username(ssh_input.username),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@strawberry.mutation(permission_classes=[IsAuthenticated])
|
||||||
|
def generate_password_reset_link(username: str) -> UserMutationReturn:
|
||||||
|
try:
|
||||||
|
password_reset_link = generate_password_reset_link_action(username=username)
|
||||||
|
except UserNotFound:
|
||||||
|
return UserMutationReturn(
|
||||||
|
success=False,
|
||||||
|
message="User not found",
|
||||||
|
code=404,
|
||||||
|
)
|
||||||
|
|
||||||
|
return UserMutationReturn(
|
||||||
|
success=True,
|
||||||
|
message="Link successfully created",
|
||||||
|
code=200,
|
||||||
|
password_reset_link=password_reset_link,
|
||||||
|
)
|
||||||
|
|
|
@ -15,12 +15,12 @@ class UserDataUser(BaseModel):
|
||||||
"""The user model from the userdata file"""
|
"""The user model from the userdata file"""
|
||||||
|
|
||||||
username: str
|
username: str
|
||||||
origin: UserDataUserOrigin
|
|
||||||
|
|
||||||
|
ssh_keys: Optional[list[str]]
|
||||||
|
user_type: Optional[UserDataUserOrigin]
|
||||||
displayname: Optional[
|
displayname: Optional[
|
||||||
str
|
str
|
||||||
] # in logic graphql will return "username" if "displayname" None
|
] # in logic graphql will return "username" if "displayname" None
|
||||||
email: Optional[str]
|
email: Optional[str]
|
||||||
ssh_keys: Optional[list[str]]
|
|
||||||
directmemberof: Optional[list[str]]
|
directmemberof: Optional[list[str]]
|
||||||
memberof: Optional[list[str]]
|
memberof: Optional[list[str]]
|
||||||
|
|
|
@ -28,3 +28,7 @@ class PasswordIsEmpty(Exception):
|
||||||
|
|
||||||
class InvalidConfiguration(Exception):
|
class InvalidConfiguration(Exception):
|
||||||
"""The userdata is broken"""
|
"""The userdata is broken"""
|
||||||
|
|
||||||
|
|
||||||
|
class SelfPrivacyAppIsOutdate(Exception):
|
||||||
|
"""SelfPrivacy app is out of date, please update. Some important functions are not working at the moment."""
|
||||||
|
|
|
@ -6,12 +6,15 @@ import re
|
||||||
import logging
|
import logging
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
from selfprivacy_api.repositories.users.exceptions import SelfPrivacyAppIsOutdate
|
||||||
from selfprivacy_api.utils import get_domain, temporary_env_var
|
from selfprivacy_api.utils import get_domain, temporary_env_var
|
||||||
from selfprivacy_api.utils.redis_pool import RedisPool
|
from selfprivacy_api.utils.redis_pool import RedisPool
|
||||||
from selfprivacy_api.models.user import UserDataUser, UserDataUserOrigin
|
from selfprivacy_api.models.user import UserDataUser, UserDataUserOrigin
|
||||||
from selfprivacy_api.repositories.users.abstract_user_repository import (
|
from selfprivacy_api.repositories.users.abstract_user_repository import (
|
||||||
AbstractUserRepository,
|
AbstractUserRepository,
|
||||||
)
|
)
|
||||||
|
from selfprivacy_api import PLEASE_UPDATE_APP_TEXT
|
||||||
|
|
||||||
|
|
||||||
KANIDM_URL = "https://127.0.0.1:3013"
|
KANIDM_URL = "https://127.0.0.1:3013"
|
||||||
|
|
||||||
|
@ -143,7 +146,7 @@ class KanidmUserRepository(AbstractUserRepository):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if password:
|
if password:
|
||||||
pass # TODO make notif
|
logger.error(PLEASE_UPDATE_APP_TEXT)
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
"attrs": {
|
"attrs": {
|
||||||
|
@ -175,27 +178,28 @@ class KanidmUserRepository(AbstractUserRepository):
|
||||||
The root user will never return.
|
The root user will never return.
|
||||||
"""
|
"""
|
||||||
users_data = KanidmUserRepository._send_query(endpoint="person", method="GET")
|
users_data = KanidmUserRepository._send_query(endpoint="person", method="GET")
|
||||||
|
|
||||||
users = []
|
users = []
|
||||||
for user in users_data:
|
for user in users_data:
|
||||||
attrs = user.get("attrs", {})
|
user_attrs = user.get("attrs", {})
|
||||||
|
|
||||||
origin = KanidmUserRepository._check_user_origin_by_memberof(
|
user_type = KanidmUserRepository._check_user_origin_by_memberof(
|
||||||
memberof=attrs.get("memberof", [])
|
memberof=user_attrs.get("memberof", [])
|
||||||
)
|
)
|
||||||
if exclude_primary and origin == UserDataUserOrigin.PRIMARY:
|
if exclude_primary and user_type == UserDataUserOrigin.PRIMARY:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
user_type = UserDataUser(
|
filled_user = UserDataUser(
|
||||||
username=attrs.get("name", [None])[0],
|
username=user_attrs.get("name", [None])[0],
|
||||||
displayname=attrs.get("displayname", [None])[0],
|
displayname=user_attrs.get("displayname", [None])[0],
|
||||||
email=attrs.get("mail", [None])[0],
|
email=user_attrs.get("mail", [None])[0],
|
||||||
ssh_keys=[], # actions layer will full in this field
|
ssh_keys=[], # actions layer will full in this field
|
||||||
origin=origin,
|
user_type=user_type,
|
||||||
directmemberof=attrs.get("directmemberof", []),
|
directmemberof=user_attrs.get("directmemberof", []),
|
||||||
memberof=attrs.get("memberof", []),
|
memberof=user_attrs.get("memberof", []),
|
||||||
)
|
)
|
||||||
|
|
||||||
users.append(user_type)
|
users.append(filled_user)
|
||||||
return users
|
return users
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -220,7 +224,7 @@ class KanidmUserRepository(AbstractUserRepository):
|
||||||
use generate_password_reset_link() instead.
|
use generate_password_reset_link() instead.
|
||||||
"""
|
"""
|
||||||
if password:
|
if password:
|
||||||
pass # TODO make notif
|
raise SelfPrivacyAppIsOutdate
|
||||||
|
|
||||||
data = {
|
data = {
|
||||||
"attrs": {
|
"attrs": {
|
||||||
|
@ -259,7 +263,7 @@ class KanidmUserRepository(AbstractUserRepository):
|
||||||
displayname=attrs.get("displayname", [None])[0],
|
displayname=attrs.get("displayname", [None])[0],
|
||||||
email=attrs.get("mail", [None])[0],
|
email=attrs.get("mail", [None])[0],
|
||||||
ssh_keys=[], # actions layer will full in this field
|
ssh_keys=[], # actions layer will full in this field
|
||||||
origin=KanidmUserRepository._check_user_origin_by_memberof(
|
user_type=KanidmUserRepository._check_user_origin_by_memberof(
|
||||||
memberof=attrs.get("memberof", [])
|
memberof=attrs.get("memberof", [])
|
||||||
),
|
),
|
||||||
directmemberof=attrs.get("directmemberof", []),
|
directmemberof=attrs.get("directmemberof", []),
|
||||||
|
|
|
@ -89,7 +89,7 @@ def no_admin_key(generic_userdata, authorized_client):
|
||||||
def admin_name() -> Optional[str]:
|
def admin_name() -> Optional[str]:
|
||||||
users = get_users()
|
users = get_users()
|
||||||
for user in users:
|
for user in users:
|
||||||
if user.origin == UserDataUserOrigin.PRIMARY:
|
if user.user_type == UserDataUserOrigin.PRIMARY:
|
||||||
return user.username
|
return user.username
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ def password_auth_spectrum(request):
|
||||||
def admin_name() -> Optional[str]:
|
def admin_name() -> Optional[str]:
|
||||||
users = get_users()
|
users = get_users()
|
||||||
for user in users:
|
for user in users:
|
||||||
if user.origin == UserDataUserOrigin.PRIMARY:
|
if user.user_type == UserDataUserOrigin.PRIMARY:
|
||||||
return user.username
|
return user.username
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue