From da5b32feebfb84bfaca44f5680819510d8c8fc57 Mon Sep 17 00:00:00 2001 From: rr- Date: Fri, 29 Apr 2016 13:08:41 +0200 Subject: [PATCH] server/users: fix hiding email from admins etc --- API.md | 3 ++- server/szurubooru/api/user_api.py | 3 ++- server/szurubooru/func/auth.py | 9 +++++---- server/szurubooru/func/users.py | 15 +++++++++------ server/szurubooru/search/search_executor.py | 1 - .../szurubooru/tests/api/test_comment_rating.py | 7 +++++-- .../tests/api/test_comment_retrieving.py | 5 +++-- .../szurubooru/tests/api/test_comment_updating.py | 1 + .../szurubooru/tests/api/test_post_favoriting.py | 7 +++++-- server/szurubooru/tests/api/test_user_creating.py | 1 + .../szurubooru/tests/api/test_user_retrieving.py | 5 +++-- .../tests/search/test_comment_search_config.py | 1 - 12 files changed, 36 insertions(+), 22 deletions(-) diff --git a/API.md b/API.md index 419527c..c36bbf6 100644 --- a/API.md +++ b/API.md @@ -1181,7 +1181,8 @@ A single user. **Field meaning** - ``: the user name. - ``: the user email. It is available only if the request is - authenticated by the same user. + authenticated by the same user, or the authenticated user can change the + email. - ``: the user rank, which effectively affects their privileges. The available ranks are stored in the server configuration. - ``: the text representation of user's rank. Like ``, the diff --git a/server/szurubooru/api/user_api.py b/server/szurubooru/api/user_api.py index ca3491c..3cb2c06 100644 --- a/server/szurubooru/api/user_api.py +++ b/server/szurubooru/api/user_api.py @@ -27,7 +27,8 @@ class UserListApi(BaseApi): ctx.get_file('avatar')) ctx.session.add(user) ctx.session.commit() - return users.serialize_user_with_details(user, ctx.user) + return users.serialize_user_with_details( + user, ctx.user, force_show_email=True) class UserDetailApi(BaseApi): def get(self, ctx, user_name): diff --git a/server/szurubooru/func/auth.py b/server/szurubooru/func/auth.py index efdd0d6..8a5edcb 100644 --- a/server/szurubooru/func/auth.py +++ b/server/szurubooru/func/auth.py @@ -36,15 +36,16 @@ def is_valid_password(user, password): ] return valid_hash in possible_hashes -def verify_privilege(user, privilege_name): - ''' Throw an AuthError if the given user doesn't have given privilege. ''' +def has_privilege(user, privilege_name): all_ranks = config.config['ranks'] - assert privilege_name in config.config['privileges'] assert user.rank in all_ranks minimal_rank = config.config['privileges'][privilege_name] good_ranks = all_ranks[all_ranks.index(minimal_rank):] - if user.rank not in good_ranks: + return user.rank in good_ranks + +def verify_privilege(user, privilege_name): + if not has_privilege(user, privilege_name): raise errors.AuthError('Insufficient privileges to do this.') def generate_authentication_token(user): diff --git a/server/szurubooru/func/users.py b/server/szurubooru/func/users.py index d0c5a49..0c9ffb1 100644 --- a/server/szurubooru/func/users.py +++ b/server/szurubooru/func/users.py @@ -13,7 +13,7 @@ class InvalidPasswordError(errors.ValidationError): pass class InvalidRankError(errors.ValidationError): pass class InvalidAvatarError(errors.ValidationError): pass -def serialize_user(user, authenticated_user): +def serialize_user(user, authenticated_user, force_show_email=False): if not user: return {} @@ -23,7 +23,8 @@ def serialize_user(user, authenticated_user): 'rankName': config.config['rank_names'].get(user.rank, 'Unknown'), 'creationTime': user.creation_time, 'lastLoginTime': user.last_login_time, - 'avatarStyle': user.avatar_style + 'avatarStyle': user.avatar_style, + 'email': user.email, } if user.avatar_style == user.AVATAR_GRAVATAR: @@ -36,13 +37,15 @@ def serialize_user(user, authenticated_user): ret['avatarUrl'] = '%s/avatars/%s.jpg' % ( config.config['data_url'].rstrip('/'), user.name.lower()) - if authenticated_user.user_id == user.user_id: - ret['email'] = user.email + if authenticated_user.user_id != user.user_id \ + and not force_show_email \ + and not auth.has_privilege(authenticated_user, 'users:edit:any:email'): + del ret['email'] return ret -def serialize_user_with_details(user, authenticated_user): - return {'user': serialize_user(user, authenticated_user)} +def serialize_user_with_details(user, authenticated_user, **kwargs): + return {'user': serialize_user(user, authenticated_user, **kwargs)} def get_user_count(): return db.session.query(db.User).count() diff --git a/server/szurubooru/search/search_executor.py b/server/szurubooru/search/search_executor.py index 0f7f303..7a3ac8a 100644 --- a/server/szurubooru/search/search_executor.py +++ b/server/szurubooru/search/search_executor.py @@ -136,7 +136,6 @@ class SearchExecutor(object): sort_desc: lambda input: input.desc(), None: lambda input: input, } - print(sort) transform = transform_map[sort] return query.order_by(transform(column)) diff --git a/server/szurubooru/tests/api/test_comment_rating.py b/server/szurubooru/tests/api/test_comment_rating.py index a5bcce8..73ad4b6 100644 --- a/server/szurubooru/tests/api/test_comment_rating.py +++ b/server/szurubooru/tests/api/test_comment_rating.py @@ -6,9 +6,12 @@ from szurubooru.func import util, comments, scores @pytest.fixture def test_ctx(config_injector, context_factory, user_factory, comment_factory): config_injector({ - 'ranks': ['anonymous', 'regular_user'], + 'ranks': ['anonymous', 'regular_user', 'mod'], 'rank_names': {'anonymous': 'Peasant', 'regular_user': 'Lord'}, - 'privileges': {'comments:score': 'regular_user'}, + 'privileges': { + 'comments:score': 'regular_user', + 'users:edit:any:email': 'mod', + }, 'thumbnails': {'avatar_width': 200}, }) db.session.flush() diff --git a/server/szurubooru/tests/api/test_comment_retrieving.py b/server/szurubooru/tests/api/test_comment_retrieving.py index 411cf56..cc9bfcb 100644 --- a/server/szurubooru/tests/api/test_comment_retrieving.py +++ b/server/szurubooru/tests/api/test_comment_retrieving.py @@ -6,13 +6,14 @@ from szurubooru.func import util, comments @pytest.fixture def test_ctx(context_factory, config_injector, user_factory, comment_factory): config_injector({ + 'ranks': ['anonymous', 'regular_user', 'mod', 'admin'], + 'rank_names': {'regular_user': 'Peasant'}, 'privileges': { 'comments:list': 'regular_user', 'comments:view': 'regular_user', + 'users:edit:any:email': 'mod', }, 'thumbnails': {'avatar_width': 200}, - 'ranks': ['anonymous', 'regular_user', 'mod', 'admin'], - 'rank_names': {'regular_user': 'Peasant'}, }) ret = util.dotdict() ret.context_factory = context_factory diff --git a/server/szurubooru/tests/api/test_comment_updating.py b/server/szurubooru/tests/api/test_comment_updating.py index a0e0a4b..0d5297b 100644 --- a/server/szurubooru/tests/api/test_comment_updating.py +++ b/server/szurubooru/tests/api/test_comment_updating.py @@ -11,6 +11,7 @@ def test_ctx(config_injector, context_factory, user_factory, comment_factory): 'privileges': { 'comments:edit:self': 'regular_user', 'comments:edit:any': 'mod', + 'users:edit:any:email': 'mod', }, 'thumbnails': {'avatar_width': 200}, }) diff --git a/server/szurubooru/tests/api/test_post_favoriting.py b/server/szurubooru/tests/api/test_post_favoriting.py index 53ed660..30c3f2d 100644 --- a/server/szurubooru/tests/api/test_post_favoriting.py +++ b/server/szurubooru/tests/api/test_post_favoriting.py @@ -6,9 +6,12 @@ from szurubooru.func import util, posts @pytest.fixture def test_ctx(config_injector, context_factory, user_factory, post_factory): config_injector({ - 'ranks': ['anonymous', 'regular_user'], + 'ranks': ['anonymous', 'regular_user', 'mod'], 'rank_names': {'anonymous': 'Peasant', 'regular_user': 'Lord'}, - 'privileges': {'posts:favorite': 'regular_user'}, + 'privileges': { + 'posts:favorite': 'regular_user', + 'users:edit:any:email': 'mod', + }, 'thumbnails': {'avatar_width': 200}, }) db.session.flush() diff --git a/server/szurubooru/tests/api/test_user_creating.py b/server/szurubooru/tests/api/test_user_creating.py index 3bb18ff..356e7e9 100644 --- a/server/szurubooru/tests/api/test_user_creating.py +++ b/server/szurubooru/tests/api/test_user_creating.py @@ -46,6 +46,7 @@ def test_creating_user(test_ctx, fake_datetime): 'name': 'chewie1', 'rank': 'admin', 'rankName': 'Unknown', + 'email': 'asd@asd.asd', } } user = users.get_user_by_name('chewie1') diff --git a/server/szurubooru/tests/api/test_user_retrieving.py b/server/szurubooru/tests/api/test_user_retrieving.py index 6d3ca88..619a77d 100644 --- a/server/szurubooru/tests/api/test_user_retrieving.py +++ b/server/szurubooru/tests/api/test_user_retrieving.py @@ -6,13 +6,14 @@ from szurubooru.func import util, users @pytest.fixture def test_ctx(context_factory, config_injector, user_factory): config_injector({ + 'ranks': ['anonymous', 'regular_user', 'mod', 'admin'], + 'rank_names': {'regular_user': 'Peasant'}, 'privileges': { 'users:list': 'regular_user', 'users:view': 'regular_user', + 'users:edit:any:email': 'mod', }, 'thumbnails': {'avatar_width': 200}, - 'ranks': ['anonymous', 'regular_user', 'mod', 'admin'], - 'rank_names': {'regular_user': 'Peasant'}, }) ret = util.dotdict() ret.context_factory = context_factory diff --git a/server/szurubooru/tests/search/test_comment_search_config.py b/server/szurubooru/tests/search/test_comment_search_config.py index 33e6510..235fcea 100644 --- a/server/szurubooru/tests/search/test_comment_search_config.py +++ b/server/szurubooru/tests/search/test_comment_search_config.py @@ -12,7 +12,6 @@ def verify_unpaged(executor): def verify(input, expected_comment_text): actual_count, actual_comments = executor.execute( input, page=1, page_size=100) - print(actual_comments) actual_comment_text = [c.text for c in actual_comments] assert actual_count == len(expected_comment_text) assert actual_comment_text == expected_comment_text