Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions app/api/helpers/user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from sqlalchemy.orm.exc import NoResultFound
from app.api.helpers.exceptions import ForbiddenException
from app.models import db
from app.api.helpers.db import save_to_db
from app.models.user import User


def modify_email_for_user_to_be_deleted(user):
"""
Update the email ID of user which is to be deleted.
Adds '.deleted' substring to email of a user to be deleted.
:param order: User to be deleted.
:return:
"""
not_unique_email = True
user_email = user.email
while not_unique_email:
try:
db.session.query(User).filter_by(email=user_email).one()
except NoResultFound:
user.email = user_email
save_to_db(user)
not_unique_email = False
else:
user_email = user_email + '.deleted'
return user


def modify_email_for_user_to_be_restored(user):
"""
Update the email ID of user which is to be restored.
Removes '.deleted' substring from a user to be restored.
:param order: User to be restored.
:return:
"""
user_email = user.email
remove_str = '.deleted'
if user_email.endswith(remove_str):
user_email = user_email[:-len(remove_str)]
try:
db.session.query(User).filter_by(email=user_email).one()
except NoResultFound:
user.email = user_email
save_to_db(user)
else:
raise ForbiddenException({'pointer': '/data/attributes/email'},
"This email is already registered! Manually edit and then try restoring")
return user
29 changes: 18 additions & 11 deletions app/api/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from app.api.helpers.mail import send_email_confirmation, send_email_change_user_email, send_email_with_action
from app.api.helpers.permission_manager import has_access
from app.api.helpers.permissions import is_user_itself
from app.api.helpers.user import modify_email_for_user_to_be_deleted, modify_email_for_user_to_be_restored
from app.api.helpers.utilities import get_serializer, str_generator
from app.api.schema.users import UserSchema, UserSchemaPublic
from app.models import db
Expand Down Expand Up @@ -207,21 +208,27 @@ def before_update_object(self, user, data, view_kwargs):
# data['small_image_url'] = uploaded_images['thumbnail_image_url']
# data['thumbnail_image_url'] = uploaded_images['thumbnail_image_url']
# data['icon_image_url'] = uploaded_images['icon_image_url']

if data.get('deleted_at') != user.deleted_at:
if has_access('is_user_itself', user_id=user.id) or has_access('is_admin'):
if data.get('deleted_at'):
if len(user.events) != 0:
raise ForbiddenException({'source': ''}, "Users associated with events cannot be deleted")
elif len(user.orders) != 0:
raise ForbiddenException({'source': ''}, "Users associated with orders cannot be deleted")
else:
modify_email_for_user_to_be_deleted(user)
else:
modify_email_for_user_to_be_restored(user)
data['email'] = user.email
user.deleted_at = data.get('deleted_at')
else:
raise ForbiddenException({'source': ''}, "You are not authorized to update this information.")

users_email = data.get('email', None)
if users_email is not None:
users_email = users_email.strip()

if has_access('is_admin') and data.get('deleted_at') != user.deleted_at:
user.deleted_at = data.get('deleted_at')

if has_access('is_user_itself', user_id=user.id) and data.get('deleted_at') != user.deleted_at:
if len(user.events) != 0:
raise ForbiddenException({'source': ''}, "Users associated with events cannot be deleted")
elif len(user.orders) != 0:
raise ForbiddenException({'source': ''}, "Users associated with orders cannot be deleted")
else:
user.deleted_at = data.get('deleted_at')

if users_email is not None and users_email != user.email:
try:
db.session.query(User).filter_by(email=users_email).one()
Expand Down
20 changes: 20 additions & 0 deletions migrations/versions/6f7b6fad3f56_refactor_deleted_users_email.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""Refactor deleted users email
Revision ID: 6f7b6fad3f56
Revises: 0e80c49a6e28
Create Date: 2019-05-24 03:26:25
"""

from alembic import op

# revision identifiers, used by Alembic.
revision = '6f7b6fad3f56'
down_revision = '0e80c49a6e28'


def upgrade():
op.execute("UPDATE users SET _email = concat(_email, '.deleted') where deleted_at IS NOT NULL;",
execution_options=None)

def downgrade():
op.execute("UPDATE users SET _email = left(_email, length(_email)-8) where right(_email, 8) = '.deleted' and deleted_at IS NOT NULL;",
execution_options=None)