server/users: fix hiding email from admins etc
This commit is contained in:
parent
d67a1b2f1c
commit
da5b32feeb
12 changed files with 36 additions and 22 deletions
3
API.md
3
API.md
|
@ -1181,7 +1181,8 @@ A single user.
|
|||
**Field meaning**
|
||||
- `<name>`: the user name.
|
||||
- `<email>`: 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.
|
||||
- `<rank>`: the user rank, which effectively affects their privileges. The
|
||||
available ranks are stored in the server configuration.
|
||||
- `<rank-name>`: the text representation of user's rank. Like `<rank>`, the
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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},
|
||||
})
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue