selfprivacy-rest-api/selfprivacy_api/graphql/mutations/users_mutations.py

173 lines
5.3 KiB
Python
Raw Normal View History

2022-07-21 00:23:59 +03:00
#!/usr/bin/env python3
"""Users management module"""
# pylint: disable=too-few-public-methods
import re
import strawberry
from selfprivacy_api.graphql import IsAuthenticated
2022-07-25 02:59:43 +03:00
from selfprivacy_api.graphql.common_types.user import (
UserMutationReturn,
get_user_by_username,
)
2022-07-21 00:23:59 +03:00
from selfprivacy_api.graphql.mutations.mutation_interface import (
2022-07-26 19:44:59 +03:00
GenericMutationReturn,
2022-07-21 00:23:59 +03:00
)
from selfprivacy_api.utils import (
WriteUserData,
ReadUserData,
is_username_forbidden,
)
2022-07-22 13:33:32 +03:00
from selfprivacy_api.utils import hash_password
2022-07-21 00:23:59 +03:00
2022-07-22 13:36:11 +03:00
2022-07-21 00:23:59 +03:00
@strawberry.input
2022-07-25 20:30:54 +03:00
class UserMutationInput:
2022-07-21 00:23:59 +03:00
"""Input type for user mutation"""
username: str
password: str
@strawberry.type
class UserMutations:
"""Mutations change user settings"""
@strawberry.mutation(permission_classes=[IsAuthenticated])
2022-07-25 20:30:54 +03:00
def create_user(self, user: UserMutationInput) -> UserMutationReturn:
2022-07-21 00:23:59 +03:00
"""Create a new user"""
2022-07-22 13:33:32 +03:00
2022-07-26 19:44:59 +03:00
# Check if password is null or none
if user.password is None or user.password == "":
return UserMutationReturn(
success=False,
message="Password is none or null",
code=400,
user=None,
)
2022-07-22 13:33:32 +03:00
hashed_password = hash_password(user.password)
2022-07-21 00:23:59 +03:00
# Check if username is forbidden
2022-07-22 13:33:32 +03:00
if is_username_forbidden(user.username):
2022-07-21 00:23:59 +03:00
return UserMutationReturn(
success=False,
2022-07-22 13:33:32 +03:00
message="Username is forbidden",
2022-07-21 00:23:59 +03:00
code=409,
user=None,
)
# Check is username passes regex
2022-07-22 13:33:32 +03:00
if not re.match(r"^[a-z_][a-z0-9_]+$", user.username):
2022-07-21 00:23:59 +03:00
return UserMutationReturn(
success=False,
2022-07-22 13:33:32 +03:00
message="Username must be alphanumeric",
2022-07-21 00:23:59 +03:00
code=400,
user=None,
)
# Check if username less than 32 characters
2022-07-22 13:33:32 +03:00
if len(user.username) >= 32:
2022-07-21 00:23:59 +03:00
return UserMutationReturn(
success=False,
2022-07-22 13:33:32 +03:00
message="Username must be less than 32 characters",
2022-07-21 00:23:59 +03:00
code=400,
user=None,
)
with ReadUserData() as data:
if "users" not in data:
data["users"] = []
# Return 409 if user already exists
2022-07-22 13:33:32 +03:00
if data["username"] == user.username:
2022-07-21 00:23:59 +03:00
return UserMutationReturn(
success=False,
2022-07-22 13:33:32 +03:00
message="User already exists",
2022-07-21 00:23:59 +03:00
code=409,
user=None,
)
2022-07-22 13:33:32 +03:00
for data_user in data["users"]:
if data_user["username"] == user.username:
2022-07-21 00:23:59 +03:00
return UserMutationReturn(
success=False,
2022-07-22 13:33:32 +03:00
message="User already exists",
2022-07-21 00:23:59 +03:00
code=409,
user=None,
)
with WriteUserData() as data:
2022-07-26 19:44:59 +03:00
if "users" not in data:
data["users"] = []
2022-07-21 00:23:59 +03:00
data["users"].append(
{
2022-07-22 13:33:32 +03:00
"username": user.username,
2022-07-21 00:23:59 +03:00
"hashedPassword": hashed_password,
}
)
return UserMutationReturn(
2022-07-22 13:33:32 +03:00
success=True,
2022-07-21 00:23:59 +03:00
message="User was successfully created!",
code=201,
user=get_user_by_username(user.username),
2022-07-21 00:23:59 +03:00
)
@strawberry.mutation(permission_classes=[IsAuthenticated])
2022-07-26 19:44:59 +03:00
def delete_user(self, username: str) -> GenericMutationReturn:
2022-07-21 00:23:59 +03:00
with WriteUserData() as data:
if username == data["username"] or username == "root":
2022-07-26 19:44:59 +03:00
return GenericMutationReturn(
2022-07-21 00:23:59 +03:00
success=False,
2022-07-22 13:33:32 +03:00
message="Cannot delete main or root user",
2022-07-21 00:23:59 +03:00
code=400,
)
# Return 404 if user does not exist
2022-07-22 13:33:32 +03:00
for data_user in data["users"]:
if data_user["username"] == username:
data["users"].remove(data_user)
2022-07-21 00:23:59 +03:00
break
else:
2022-07-26 19:44:59 +03:00
return GenericMutationReturn(
2022-07-21 00:23:59 +03:00
success=False,
2022-07-22 13:33:32 +03:00
message="User does not exist",
2022-07-21 00:23:59 +03:00
code=404,
)
2022-07-26 19:44:59 +03:00
return GenericMutationReturn(
2022-07-21 00:23:59 +03:00
success=True,
2022-07-22 13:33:32 +03:00
message="User was deleted",
2022-07-21 00:23:59 +03:00
code=200,
)
@strawberry.mutation(permission_classes=[IsAuthenticated])
2022-07-25 20:30:54 +03:00
def update_user(self, user: UserMutationInput) -> UserMutationReturn:
2022-07-21 00:23:59 +03:00
"""Update user mutation"""
2022-07-22 13:33:32 +03:00
hashed_password = hash_password(user.password)
2022-07-21 00:23:59 +03:00
with WriteUserData() as data:
2022-07-22 13:33:32 +03:00
if user.username == data["username"]:
2022-07-21 00:23:59 +03:00
data["hashedMasterPassword"] = hashed_password
# Return 404 if user does not exist
else:
2022-07-22 13:33:32 +03:00
for data_user in data["users"]:
if data_user["username"] == user.username:
data_user["hashedPassword"] = hashed_password
2022-07-21 00:23:59 +03:00
break
else:
return UserMutationReturn(
success=False,
2022-07-22 13:33:32 +03:00
message="User does not exist",
2022-07-21 00:23:59 +03:00
code=404,
user=None,
)
return UserMutationReturn(
success=True,
message="User was successfully updated",
code=200,
user=get_user_by_username(user.username),
2022-07-21 00:23:59 +03:00
)