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 (
|
|
|
|
MutationReturnInterface,
|
|
|
|
)
|
2022-07-23 12:39:52 +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
|
|
|
|
|
|
|
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:
|
|
|
|
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,
|
2022-07-23 12:39:52 +03:00
|
|
|
user=get_user_by_username(user.username),
|
2022-07-21 00:23:59 +03:00
|
|
|
)
|
|
|
|
|
|
|
|
@strawberry.mutation(permission_classes=[IsAuthenticated])
|
|
|
|
def delete_user(self, username: str) -> MutationReturnInterface:
|
|
|
|
with WriteUserData() as data:
|
|
|
|
|
|
|
|
if username == data["username"] or username == "root":
|
|
|
|
return MutationReturnInterface(
|
|
|
|
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:
|
|
|
|
return MutationReturnInterface(
|
|
|
|
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,
|
|
|
|
)
|
|
|
|
|
|
|
|
return MutationReturnInterface(
|
|
|
|
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,
|
2022-07-23 12:39:52 +03:00
|
|
|
user=get_user_by_username(user.username),
|
2022-07-21 00:23:59 +03:00
|
|
|
)
|