import graphene from django.contrib.auth import update_session_auth_hash from django.core.exceptions import PermissionDenied from graphene import relay from api.utils import get_object from users.inputs import PasswordUpdateInput from users.models import SchoolClass, UserSetting from users.serializers import PasswordSerialzer, AvatarUrlSerializer class FieldError(graphene.ObjectType): code = graphene.String() class UpdateError(graphene.ObjectType): field = graphene.String() errors = graphene.List(FieldError) class UpdatePassword(relay.ClientIDMutation): class Input: password_input = graphene.Argument(PasswordUpdateInput) success = graphene.Boolean() errors = graphene.List(UpdateError) # todo: change for consistency @classmethod def mutate_and_get_payload(cls, root, info, **kwargs): user = info.context.user password_data = kwargs.get('password_input') serializer = PasswordSerialzer(data=password_data, context=user) if serializer.is_valid(): user.set_password(password_data['new_password']) user.save() update_session_auth_hash(info.context, user) return cls(success=True) errors = [] for key, value in serializer.errors.items(): error = UpdateError(field=key, errors=[]) for field_error in serializer.errors[key]: error.errors.append(FieldError(code=field_error.code)) errors.append(error) return cls(success=False, errors=errors) class UpdateAvatar(relay.ClientIDMutation): class Input: avatar_url = graphene.String() success = graphene.Boolean() errors = graphene.List(UpdateError) # todo: change for consistency @classmethod def mutate_and_get_payload(cls, root, info, **kwargs): user = info.context.user avatar_data = kwargs.get('avatar_url') serializer = AvatarUrlSerializer(data={'avatar_url': avatar_data}) if serializer.is_valid(): user.avatar_url = avatar_data user.save() return cls(success=True) errors = [] for key, value in serializer.errors.items(): error = UpdateError(field=key, errors=[]) for field_error in serializer.errors[key]: error.errors.append(FieldError(code=field_error.code)) errors.append(error) return cls(success=False, errors=errors) class UpdateSetting(relay.ClientIDMutation): class Input: id = graphene.ID(required=True) @classmethod def mutate_and_get_payload(cls, root, info, **kwargs): class_id = kwargs.get('id') school_class = get_object(SchoolClass, class_id) user = info.context.user if school_class and school_class not in user.school_classes.all(): raise PermissionDenied('Permission denied: Incorrect school class') user_settings, created = UserSetting.objects.get_or_create(user=user) user_settings.selected_class = school_class user_settings.save() return cls(success=True) success = graphene.Boolean() errors = graphene.List(UpdateError) class ProfileMutations: update_password = UpdatePassword.Field() update_avatar = UpdateAvatar.Field() update_setting = UpdateSetting.Field()