server/users: hardcode available ranks

This commit is contained in:
rr- 2016-05-08 16:59:25 +02:00
parent 58964bcdc9
commit 198cb0af3e
37 changed files with 359 additions and 383 deletions

20
API.md
View file

@ -1122,9 +1122,8 @@ data.
style can be either `gravatar` or `manual`. `manual` avatar style requires style can be either `gravatar` or `manual`. `manual` avatar style requires
client to pass also `avatar` file - see [file uploads](#file-uploads) for client to pass also `avatar` file - see [file uploads](#file-uploads) for
details. If the rank is empty and the user happens to be the first user details. If the rank is empty and the user happens to be the first user
ever created, they're granted highest available rank, becoming an ever created, become an administrator, whereas subsequent users will be
administrator, whereas subsequent users will be given the rank indicated by given the rank indicated by `default_rank` in the server's configuration.
`default_rank` in the server's configuration.
## Updating user ## Updating user
- **Request** - **Request**
@ -1342,7 +1341,6 @@ A single user.
"name": <name>, "name": <name>,
"email": <email>, "email": <email>,
"rank": <rank>, "rank": <rank>,
"rankName": <rank-name>,
"lastLoginTime": <last-login-time>, "lastLoginTime": <last-login-time>,
"creationTime": <creation-time>, "creationTime": <creation-time>,
"avatarStyle": <avatar-style>, "avatarStyle": <avatar-style>,
@ -1355,10 +1353,16 @@ A single user.
- `<email>`: the user email. It is available only if the request is - `<email>`: the user email. It is available only if the request is
authenticated by the same user, or the authenticated user can change the authenticated by the same user, or the authenticated user can change the
email. email.
- `<rank>`: the user rank, which effectively affects their privileges. The - `<rank>`: the user rank, which effectively affects their privileges.
available ranks are stored in the server configuration.
- `<rank-name>`: the text representation of user's rank. Like `<rank>`, the Possible values:
possible values depend on the server configuration.
- `"restricted"`: restricted user
- `"regular"`: regular user
- `"power"`: power user
- `"moderator"`: moderator
- `"administrator"`: administrator
- `<last-login-time>`: the last login time, formatted as per RFC 3339. - `<last-login-time>`: the last login time, formatted as per RFC 3339.
- `<creation-time>`: the user registration time, formatted as per RFC 3339. - `<creation-time>`: the user registration time, formatted as per RFC 3339.
- `<avatarStyle>`: how to render the user avatar. - `<avatarStyle>`: how to render the user avatar.

View file

@ -11,6 +11,15 @@ class Api {
this.userName = null; this.userName = null;
this.userPassword = null; this.userPassword = null;
this.cache = {}; this.cache = {};
this.allRanks = [
'anonymous',
'restricted',
'regular',
'power',
'moderator',
'administrator',
'nobody',
];
} }
get(url) { get(url) {
@ -75,7 +84,7 @@ class Api {
continue; continue;
} }
const rankName = config.privileges[privilege]; const rankName = config.privileges[privilege];
const rankIndex = config.ranks.indexOf(rankName); const rankIndex = this.allRanks.indexOf(rankName);
if (minViableRank === null || rankIndex < minViableRank) { if (minViableRank === null || rankIndex < minViableRank) {
minViableRank = rankIndex; minViableRank = rankIndex;
} }
@ -84,7 +93,7 @@ class Api {
console.error('Bad privilege name: ' + lookup); console.error('Bad privilege name: ' + lookup);
} }
let myRank = this.user !== null ? let myRank = this.user !== null ?
config.ranks.indexOf(this.user.rank) : this.allRanks.indexOf(this.user.rank) :
0; 0;
return myRank >= minViableRank; return myRank >= minViableRank;
} }

View file

@ -14,6 +14,16 @@ const UserListHeaderView = require('../views/user_list_header_view.js');
const UserListPageView = require('../views/user_list_page_view.js'); const UserListPageView = require('../views/user_list_page_view.js');
const EmptyView = require('../views/empty_view.js'); const EmptyView = require('../views/empty_view.js');
const rankNames = {
anonymous: 'Anonymous',
restricted: 'Restricted user',
regular: 'Regular user',
power: 'Power user',
moderator: 'Moderator',
administrator: 'Administrator',
nobody: 'Nobody',
};
class UsersController { class UsersController {
constructor() { constructor() {
this.registrationView = new RegistrationView(); this.registrationView = new RegistrationView();
@ -86,6 +96,7 @@ class UsersController {
next(); next();
} else { } else {
api.get('/user/' + ctx.params.name).then(response => { api.get('/user/' + ctx.params.name).then(response => {
response.user.rankName = rankNames[response.user.rank];
ctx.state.user = response.user; ctx.state.user = response.user;
ctx.save(); ctx.save();
this.user = response.user; this.user = response.user;
@ -209,18 +220,17 @@ class UsersController {
const isLoggedIn = api.isLoggedIn(user); const isLoggedIn = api.isLoggedIn(user);
const infix = isLoggedIn ? 'self' : 'any'; const infix = isLoggedIn ? 'self' : 'any';
const myRankIdx = api.user ? config.ranks.indexOf(api.user.rank) : 0; const myRankIdx = api.user ? api.allRanks.indexOf(api.user.rank) : 0;
const rankNames = Object.values(config.rankNames);
let ranks = {}; let ranks = {};
for (let rankIdx of misc.range(config.ranks.length)) { for (let rankIdx of misc.range(api.allRanks.length)) {
const rankIdentifier = config.ranks[rankIdx]; const rankIdentifier = api.allRanks[rankIdx];
if (rankIdentifier === 'anonymous') { if (rankIdentifier === 'anonymous') {
continue; continue;
} }
if (rankIdx > myRankIdx) { if (rankIdx > myRankIdx) {
continue; continue;
} }
ranks[rankIdentifier] = rankNames[rankIdx]; ranks[rankIdentifier] = Object.values(rankNames)[rankIdx];
} }
if (isLoggedIn) { if (isLoggedIn) {

View file

@ -39,22 +39,7 @@ limits:
tag_name_regex: ^:?[a-zA-Z0-9_-]+$ tag_name_regex: ^:?[a-zA-Z0-9_-]+$
tag_category_name_regex: ^.{1,}$ tag_category_name_regex: ^.{1,}$
# changing ranks after deployment may require manual tweaks to the database. default_rank: regular
ranks:
- anonymous
- regular_user
- power_user
- mod
- admin
- nobody
rank_names:
anonymous: 'Anonymous user'
regular_user: 'Regular user'
power_user: 'Power user'
mod: 'Moderator'
admin: 'Administrator'
nobody: 'God'
default_rank: regular_user
# don't change these, unless you want to annoy people. if you do customize # don't change these, unless you want to annoy people. if you do customize
# them though, make sure to update the instructions in the registration form # them though, make sure to update the instructions in the registration form
@ -64,63 +49,63 @@ user_name_regex: '^[a-zA-Z0-9_-]{1,32}$'
privileges: privileges:
'users:create': anonymous 'users:create': anonymous
'users:list': regular_user 'users:list': regular
'users:view': regular_user 'users:view': regular
'users:edit:any:name': mod 'users:edit:any:name': moderator
'users:edit:any:pass': mod 'users:edit:any:pass': moderator
'users:edit:any:email': mod 'users:edit:any:email': moderator
'users:edit:any:avatar': mod 'users:edit:any:avatar': moderator
'users:edit:any:rank': mod 'users:edit:any:rank': moderator
'users:edit:self:name': regular_user 'users:edit:self:name': regular
'users:edit:self:pass': regular_user 'users:edit:self:pass': regular
'users:edit:self:email': regular_user 'users:edit:self:email': regular
'users:edit:self:avatar': regular_user 'users:edit:self:avatar': regular
'users:edit:self:rank': mod # one can't promote themselves or anyone to upper rank than their own. 'users:edit:self:rank': moderator # one can't promote themselves or anyone to upper rank than their own.
'users:delete:any': admin 'users:delete:any': administrator
'users:delete:self': regular_user 'users:delete:self': regular
'posts:create:anonymous': regular_user 'posts:create:anonymous': regular
'posts:create:identified': regular_user 'posts:create:identified': regular
'posts:list': anonymous 'posts:list': anonymous
'posts:view': anonymous 'posts:view': anonymous
'posts:edit:content': power_user 'posts:edit:content': power
'posts:edit:flags': regular_user 'posts:edit:flags': regular
'posts:edit:notes': regular_user 'posts:edit:notes': regular
'posts:edit:relations': regular_user 'posts:edit:relations': regular
'posts:edit:safety': power_user 'posts:edit:safety': power
'posts:edit:source': regular_user 'posts:edit:source': regular
'posts:edit:tags': regular_user 'posts:edit:tags': regular
'posts:edit:thumbnail': power_user 'posts:edit:thumbnail': power
'posts:feature': mod 'posts:feature': moderator
'posts:delete': mod 'posts:delete': moderator
'posts:score': regular_user 'posts:score': regular
'posts:favorite': regular_user 'posts:favorite': regular
'tags:create': regular_user 'tags:create': regular
'tags:edit:names': power_user 'tags:edit:names': power
'tags:edit:category': power_user 'tags:edit:category': power
'tags:edit:implications': power_user 'tags:edit:implications': power
'tags:edit:suggestions': power_user 'tags:edit:suggestions': power
'tags:list': regular_user # note: will be available as data_url/tags.json anyway 'tags:list': regular # note: will be available as data_url/tags.json anyway
'tags:view': anonymous 'tags:view': anonymous
'tags:masstag': power_user 'tags:masstag': power
'tags:merge': mod 'tags:merge': moderator
'tags:delete': mod 'tags:delete': moderator
'tag_categories:create': mod 'tag_categories:create': moderator
'tag_categories:edit:name': mod 'tag_categories:edit:name': moderator
'tag_categories:edit:color': mod 'tag_categories:edit:color': moderator
'tag_categories:list': anonymous # note: will be available as data_url/tags.json anyway 'tag_categories:list': anonymous # note: will be available as data_url/tags.json anyway
'tag_categories:view': anonymous 'tag_categories:view': anonymous
'tag_categories:delete': mod 'tag_categories:delete': moderator
'comments:create': regular_user 'comments:create': regular
'comments:delete:any': mod 'comments:delete:any': moderator
'comments:delete:own': regular_user 'comments:delete:own': regular
'comments:edit:any': mod 'comments:edit:any': moderator
'comments:edit:own': regular_user 'comments:edit:own': regular
'comments:list': regular_user 'comments:list': regular
'comments:view': regular_user 'comments:view': regular
'comments:score': regular_user 'comments:score': regular
'snapshots:list': power_user 'snapshots:list': power

View file

@ -26,15 +26,12 @@ def validate_config(src):
Check whether config doesn't contain errors that might prove Check whether config doesn't contain errors that might prove
lethal at runtime. lethal at runtime.
''' '''
all_ranks = src['ranks'] from szurubooru.db.user import User
for privilege, rank in src['privileges'].items(): for privilege, rank in src['privileges'].items():
if rank not in all_ranks: if rank not in User.ALL_RANKS:
raise errors.ConfigError( raise errors.ConfigError(
'Rank %r for privilege %r is missing' % (rank, privilege)) 'Rank %r for privilege %r is missing' % (rank, privilege))
for rank in ['anonymous', 'admin', 'nobody']: if src['default_rank'] not in User.ALL_RANKS:
if rank not in all_ranks:
raise errors.ConfigError('Protected rank %r is missing' % rank)
if src['default_rank'] not in all_ranks:
raise errors.ConfigError( raise errors.ConfigError(
'Default rank %r is not on the list of known ranks' % ( 'Default rank %r is not on the list of known ranks' % (
src['default_rank'])) src['default_rank']))

View file

@ -7,6 +7,23 @@ class User(Base):
AVATAR_GRAVATAR = 'gravatar' AVATAR_GRAVATAR = 'gravatar'
AVATAR_MANUAL = 'manual' AVATAR_MANUAL = 'manual'
RANK_ANONYMOUS = 'anonymous'
RANK_RESTRICTED = 'restricted'
RANK_REGULAR = 'regular'
RANK_POWER = 'power'
RANK_MODERATOR = 'moderator'
RANK_ADMINISTRATOR = 'administrator'
RANK_NOBODY = 'nobody'
ALL_RANKS = [
RANK_ANONYMOUS,
RANK_RESTRICTED,
RANK_REGULAR,
RANK_POWER,
RANK_MODERATOR,
RANK_ADMINISTRATOR,
RANK_NOBODY, # nobody can have higher privileges than administrator
]
user_id = Column('id', Integer, primary_key=True) user_id = Column('id', Integer, primary_key=True)
name = Column('name', String(50), nullable=False, unique=True) name = Column('name', String(50), nullable=False, unique=True)
password_hash = Column('password_hash', String(64), nullable=False) password_hash = Column('password_hash', String(64), nullable=False)

View file

@ -1,7 +1,6 @@
import hashlib import hashlib
import random import random
from szurubooru import config from szurubooru import config, db, errors
from szurubooru import errors
def get_password_hash(salt, password): def get_password_hash(salt, password):
''' Retrieve new-style password hash. ''' ''' Retrieve new-style password hash. '''
@ -37,11 +36,10 @@ def is_valid_password(user, password):
return valid_hash in possible_hashes return valid_hash in possible_hashes
def has_privilege(user, privilege_name): def has_privilege(user, privilege_name):
all_ranks = config.config['ranks']
assert privilege_name in config.config['privileges'] assert privilege_name in config.config['privileges']
assert user.rank in all_ranks assert user.rank in db.User.ALL_RANKS
minimal_rank = config.config['privileges'][privilege_name] minimal_rank = config.config['privileges'][privilege_name]
good_ranks = all_ranks[all_ranks.index(minimal_rank):] good_ranks = db.User.ALL_RANKS[db.User.ALL_RANKS.index(minimal_rank):]
return user.rank in good_ranks return user.rank in good_ranks
def verify_privilege(user, privilege_name): def verify_privilege(user, privilege_name):

View file

@ -19,7 +19,6 @@ def serialize_user(user, authenticated_user, force_show_email=False):
ret = { ret = {
'name': user.name, 'name': user.name,
'rank': user.rank, 'rank': user.rank,
'rankName': config.config['rank_names'].get(user.rank, 'Unknown'),
'creationTime': user.creation_time, 'creationTime': user.creation_time,
'lastLoginTime': user.last_login_time, 'lastLoginTime': user.last_login_time,
'avatarStyle': user.avatar_style, 'avatarStyle': user.avatar_style,
@ -81,7 +80,7 @@ def create_user(name, password, email, auth_user):
if get_user_count() > 0: if get_user_count() > 0:
user.rank = config.config['default_rank'] user.rank = config.config['default_rank']
else: else:
user.rank = 'admin' user.rank = db.User.RANK_ADMINISTRATOR
user.creation_time = datetime.datetime.now() user.creation_time = datetime.datetime.now()
user.avatar_style = db.User.AVATAR_GRAVATAR user.avatar_style = db.User.AVATAR_GRAVATAR
return user return user
@ -126,12 +125,11 @@ def update_user_rank(user, rank, authenticated_user):
if not rank: if not rank:
raise InvalidRankError('Rank cannot be empty.') raise InvalidRankError('Rank cannot be empty.')
rank = rank.strip() rank = rank.strip()
available_ranks = config.config['ranks'] if not rank in db.User.ALL_RANKS:
if not rank in available_ranks:
raise InvalidRankError( raise InvalidRankError(
'Rank %r is invalid. Valid ranks: %r' % (rank, available_ranks)) 'Rank %r is invalid. Valid ranks: %r' % (rank, db.User.ALL_RANKS))
if available_ranks.index(authenticated_user.rank) \ if db.User.ALL_RANKS.index(authenticated_user.rank) \
< available_ranks.index(rank) and get_user_count() > 0: < db.User.ALL_RANKS.index(rank) and get_user_count() > 0:
raise errors.AuthError('Trying to set higher rank than your own.') raise errors.AuthError('Trying to set higher rank than your own.')
user.rank = rank user.rank = rank

View file

@ -9,9 +9,7 @@ def test_ctx(
config_injector({ config_injector({
'data_dir': str(tmpdir), 'data_dir': str(tmpdir),
'data_url': 'http://example.com', 'data_url': 'http://example.com',
'ranks': ['anonymous', 'regular_user'], 'privileges': {'comments:create': db.User.RANK_REGULAR},
'rank_names': {'anonymous': 'Peasant', 'regular_user': 'Lord'},
'privileges': {'comments:create': 'regular_user'},
'thumbnails': {'avatar_width': 200}, 'thumbnails': {'avatar_width': 200},
}) })
ret = util.dotdict() ret = util.dotdict()
@ -23,7 +21,7 @@ def test_ctx(
def test_creating_comment(test_ctx, fake_datetime): def test_creating_comment(test_ctx, fake_datetime):
post = test_ctx.post_factory() post = test_ctx.post_factory()
user = test_ctx.user_factory(rank='regular_user') user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
db.session.add_all([post, user]) db.session.add_all([post, user])
db.session.flush() db.session.flush()
with fake_datetime('1997-01-01'): with fake_datetime('1997-01-01'):
@ -52,7 +50,7 @@ def test_creating_comment(test_ctx, fake_datetime):
]) ])
def test_trying_to_pass_invalid_input(test_ctx, input): def test_trying_to_pass_invalid_input(test_ctx, input):
post = test_ctx.post_factory() post = test_ctx.post_factory()
user = test_ctx.user_factory(rank='regular_user') user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
db.session.add_all([post, user]) db.session.add_all([post, user])
db.session.flush() db.session.flush()
real_input = {'text': 'input', 'postId': post.post_id} real_input = {'text': 'input', 'postId': post.post_id}
@ -73,10 +71,10 @@ def test_trying_to_omit_mandatory_field(test_ctx, field):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input={}, input={},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
def test_trying_to_comment_non_existing(test_ctx): def test_trying_to_comment_non_existing(test_ctx):
user = test_ctx.user_factory(rank='regular_user') user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
db.session.add_all([user]) db.session.add_all([user])
db.session.flush() db.session.flush()
with pytest.raises(posts.PostNotFoundError): with pytest.raises(posts.PostNotFoundError):

View file

@ -7,10 +7,9 @@ from szurubooru.func import util, comments
def test_ctx(config_injector, context_factory, user_factory, comment_factory): def test_ctx(config_injector, context_factory, user_factory, comment_factory):
config_injector({ config_injector({
'privileges': { 'privileges': {
'comments:delete:self': 'regular_user', 'comments:delete:self': db.User.RANK_REGULAR,
'comments:delete:any': 'mod', 'comments:delete:any': db.User.RANK_MODERATOR,
}, },
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
}) })
ret = util.dotdict() ret = util.dotdict()
ret.context_factory = context_factory ret.context_factory = context_factory
@ -30,8 +29,8 @@ def test_deleting_own_comment(test_ctx):
assert db.session.query(db.Comment).count() == 0 assert db.session.query(db.Comment).count() == 0
def test_deleting_someones_else_comment(test_ctx): def test_deleting_someones_else_comment(test_ctx):
user1 = test_ctx.user_factory(rank='regular_user') user1 = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(rank='mod') user2 = test_ctx.user_factory(rank=db.User.RANK_MODERATOR)
comment = test_ctx.comment_factory(user=user1) comment = test_ctx.comment_factory(user=user1)
db.session.add(comment) db.session.add(comment)
db.session.commit() db.session.commit()
@ -40,8 +39,8 @@ def test_deleting_someones_else_comment(test_ctx):
assert db.session.query(db.Comment).count() == 0 assert db.session.query(db.Comment).count() == 0
def test_trying_to_delete_someones_else_comment_without_privileges(test_ctx): def test_trying_to_delete_someones_else_comment_without_privileges(test_ctx):
user1 = test_ctx.user_factory(rank='regular_user') user1 = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(rank='regular_user') user2 = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
comment = test_ctx.comment_factory(user=user1) comment = test_ctx.comment_factory(user=user1)
db.session.add(comment) db.session.add(comment)
db.session.commit() db.session.commit()
@ -54,4 +53,4 @@ def test_trying_to_delete_non_existing(test_ctx):
with pytest.raises(comments.CommentNotFoundError): with pytest.raises(comments.CommentNotFoundError):
test_ctx.api.delete( test_ctx.api.delete(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 1) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 1)

View file

@ -9,11 +9,9 @@ def test_ctx(
config_injector({ config_injector({
'data_dir': str(tmpdir), 'data_dir': str(tmpdir),
'data_url': 'http://example.com', 'data_url': 'http://example.com',
'ranks': ['anonymous', 'regular_user', 'mod'],
'rank_names': {'anonymous': 'Peasant', 'regular_user': 'Lord'},
'privileges': { 'privileges': {
'comments:score': 'regular_user', 'comments:score': db.User.RANK_REGULAR,
'users:edit:any:email': 'mod', 'users:edit:any:email': db.User.RANK_MODERATOR,
}, },
'thumbnails': {'avatar_width': 200}, 'thumbnails': {'avatar_width': 200},
}) })
@ -26,7 +24,7 @@ def test_ctx(
return ret return ret
def test_simple_rating(test_ctx, fake_datetime): def test_simple_rating(test_ctx, fake_datetime):
user = test_ctx.user_factory(rank='regular_user') user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
comment = test_ctx.comment_factory(user=user) comment = test_ctx.comment_factory(user=user)
db.session.add(comment) db.session.add(comment)
db.session.commit() db.session.commit()
@ -42,7 +40,7 @@ def test_simple_rating(test_ctx, fake_datetime):
assert comment.score == 1 assert comment.score == 1
def test_updating_rating(test_ctx, fake_datetime): def test_updating_rating(test_ctx, fake_datetime):
user = test_ctx.user_factory(rank='regular_user') user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
comment = test_ctx.comment_factory(user=user) comment = test_ctx.comment_factory(user=user)
db.session.add(comment) db.session.add(comment)
db.session.commit() db.session.commit()
@ -59,7 +57,7 @@ def test_updating_rating(test_ctx, fake_datetime):
assert comment.score == -1 assert comment.score == -1
def test_updating_rating_to_zero(test_ctx, fake_datetime): def test_updating_rating_to_zero(test_ctx, fake_datetime):
user = test_ctx.user_factory(rank='regular_user') user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
comment = test_ctx.comment_factory(user=user) comment = test_ctx.comment_factory(user=user)
db.session.add(comment) db.session.add(comment)
db.session.commit() db.session.commit()
@ -76,7 +74,7 @@ def test_updating_rating_to_zero(test_ctx, fake_datetime):
assert comment.score == 0 assert comment.score == 0
def test_deleting_rating(test_ctx, fake_datetime): def test_deleting_rating(test_ctx, fake_datetime):
user = test_ctx.user_factory(rank='regular_user') user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
comment = test_ctx.comment_factory(user=user) comment = test_ctx.comment_factory(user=user)
db.session.add(comment) db.session.add(comment)
db.session.commit() db.session.commit()
@ -92,8 +90,8 @@ def test_deleting_rating(test_ctx, fake_datetime):
assert comment.score == 0 assert comment.score == 0
def test_ratings_from_multiple_users(test_ctx, fake_datetime): def test_ratings_from_multiple_users(test_ctx, fake_datetime):
user1 = test_ctx.user_factory(rank='regular_user') user1 = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(rank='regular_user') user2 = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
comment = test_ctx.comment_factory() comment = test_ctx.comment_factory()
db.session.add_all([user1, user2, comment]) db.session.add_all([user1, user2, comment])
db.session.commit() db.session.commit()
@ -141,7 +139,7 @@ def test_trying_to_update_non_existing(test_ctx):
test_ctx.api.put( test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(
input={'score': 1}, input={'score': 1},
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
5) 5)
def test_trying_to_rate_without_privileges(test_ctx): def test_trying_to_rate_without_privileges(test_ctx):

View file

@ -9,12 +9,10 @@ def test_ctx(
config_injector({ config_injector({
'data_dir': str(tmpdir), 'data_dir': str(tmpdir),
'data_url': 'http://example.com', 'data_url': 'http://example.com',
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {'regular_user': 'Peasant'},
'privileges': { 'privileges': {
'comments:list': 'regular_user', 'comments:list': db.User.RANK_REGULAR,
'comments:view': 'regular_user', 'comments:view': db.User.RANK_REGULAR,
'users:edit:any:email': 'mod', 'users:edit:any:email': db.User.RANK_MODERATOR,
}, },
'thumbnails': {'avatar_width': 200}, 'thumbnails': {'avatar_width': 200},
}) })
@ -33,7 +31,7 @@ def test_retrieving_multiple(test_ctx):
result = test_ctx.list_api.get( result = test_ctx.list_api.get(
test_ctx.context_factory( test_ctx.context_factory(
input={'query': '', 'page': 1}, input={'query': '', 'page': 1},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['query'] == '' assert result['query'] == ''
assert result['page'] == 1 assert result['page'] == 1
assert result['pageSize'] == 100 assert result['pageSize'] == 100
@ -53,7 +51,7 @@ def test_retrieving_single(test_ctx):
db.session.flush() db.session.flush()
result = test_ctx.detail_api.get( result = test_ctx.detail_api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
comment.comment_id) comment.comment_id)
assert 'comment' in result assert 'comment' in result
assert 'id' in result['comment'] assert 'id' in result['comment']
@ -69,7 +67,7 @@ def test_trying_to_retrieve_single_non_existing(test_ctx):
with pytest.raises(comments.CommentNotFoundError): with pytest.raises(comments.CommentNotFoundError):
test_ctx.detail_api.get( test_ctx.detail_api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
5) 5)
def test_trying_to_retrieve_single_without_privileges(test_ctx): def test_trying_to_retrieve_single_without_privileges(test_ctx):

View file

@ -9,12 +9,10 @@ def test_ctx(
config_injector({ config_injector({
'data_dir': str(tmpdir), 'data_dir': str(tmpdir),
'data_url': 'http://example.com', 'data_url': 'http://example.com',
'ranks': ['anonymous', 'regular_user', 'mod'],
'rank_names': {'anonymous': 'Peasant', 'regular_user': 'Lord', 'mod': 'King'},
'privileges': { 'privileges': {
'comments:edit:self': 'regular_user', 'comments:edit:self': db.User.RANK_REGULAR,
'comments:edit:any': 'mod', 'comments:edit:any': db.User.RANK_MODERATOR,
'users:edit:any:email': 'mod', 'users:edit:any:email': db.User.RANK_MODERATOR,
}, },
'thumbnails': {'avatar_width': 200}, 'thumbnails': {'avatar_width': 200},
}) })
@ -27,7 +25,7 @@ def test_ctx(
return ret return ret
def test_simple_updating(test_ctx, fake_datetime): def test_simple_updating(test_ctx, fake_datetime):
user = test_ctx.user_factory(rank='regular_user') user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
comment = test_ctx.comment_factory(user=user) comment = test_ctx.comment_factory(user=user)
db.session.add(comment) db.session.add(comment)
db.session.commit() db.session.commit()
@ -73,12 +71,12 @@ def test_trying_to_update_non_existing(test_ctx):
test_ctx.api.put( test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(
input={'text': 'new text'}, input={'text': 'new text'},
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
5) 5)
def test_trying_to_update_someones_comment_without_privileges(test_ctx): def test_trying_to_update_someones_comment_without_privileges(test_ctx):
user = test_ctx.user_factory(rank='regular_user') user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(rank='regular_user') user2 = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
comment = test_ctx.comment_factory(user=user) comment = test_ctx.comment_factory(user=user)
db.session.add(comment) db.session.add(comment)
db.session.commit() db.session.commit()
@ -88,8 +86,8 @@ def test_trying_to_update_someones_comment_without_privileges(test_ctx):
comment.comment_id) comment.comment_id)
def test_updating_someones_comment_with_privileges(test_ctx): def test_updating_someones_comment_with_privileges(test_ctx):
user = test_ctx.user_factory(rank='regular_user') user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(rank='mod') user2 = test_ctx.user_factory(rank=db.User.RANK_MODERATOR)
comment = test_ctx.comment_factory(user=user) comment = test_ctx.comment_factory(user=user)
db.session.add(comment) db.session.add(comment)
db.session.commit() db.session.commit()

View file

@ -16,7 +16,7 @@ def password_reset_api(config_injector):
def test_reset_sending_email( def test_reset_sending_email(
password_reset_api, context_factory, user_factory): password_reset_api, context_factory, user_factory):
db.session.add(user_factory( db.session.add(user_factory(
name='u1', rank='regular_user', email='user@example.com')) name='u1', rank=db.User.RANK_REGULAR, email='user@example.com'))
for getter in ['u1', 'user@example.com']: for getter in ['u1', 'user@example.com']:
mailer.send_mail = mock.MagicMock() mailer.send_mail = mock.MagicMock()
assert password_reset_api.get(context_factory(), getter) == {} assert password_reset_api.get(context_factory(), getter) == {}
@ -35,14 +35,14 @@ def test_trying_to_reset_non_existing(password_reset_api, context_factory):
def test_trying_to_reset_without_email( def test_trying_to_reset_without_email(
password_reset_api, context_factory, user_factory): password_reset_api, context_factory, user_factory):
db.session.add(user_factory(name='u1', rank='regular_user', email=None)) db.session.add(user_factory(name='u1', rank=db.User.RANK_REGULAR, email=None))
with pytest.raises(errors.ValidationError): with pytest.raises(errors.ValidationError):
password_reset_api.get(context_factory(), 'u1') password_reset_api.get(context_factory(), 'u1')
def test_confirming_with_good_token( def test_confirming_with_good_token(
password_reset_api, context_factory, user_factory): password_reset_api, context_factory, user_factory):
user = user_factory( user = user_factory(
name='u1', rank='regular_user', email='user@example.com') name='u1', rank=db.User.RANK_REGULAR, email='user@example.com')
old_hash = user.password_hash old_hash = user.password_hash
db.session.add(user) db.session.add(user)
context = context_factory( context = context_factory(
@ -58,14 +58,14 @@ def test_trying_to_confirm_non_existing(password_reset_api, context_factory):
def test_trying_to_confirm_without_token( def test_trying_to_confirm_without_token(
password_reset_api, context_factory, user_factory): password_reset_api, context_factory, user_factory):
db.session.add(user_factory( db.session.add(user_factory(
name='u1', rank='regular_user', email='user@example.com')) name='u1', rank=db.User.RANK_REGULAR, email='user@example.com'))
with pytest.raises(errors.ValidationError): with pytest.raises(errors.ValidationError):
password_reset_api.post(context_factory(input={}), 'u1') password_reset_api.post(context_factory(input={}), 'u1')
def test_trying_to_confirm_with_bad_token( def test_trying_to_confirm_with_bad_token(
password_reset_api, context_factory, user_factory): password_reset_api, context_factory, user_factory):
db.session.add(user_factory( db.session.add(user_factory(
name='u1', rank='regular_user', email='user@example.com')) name='u1', rank=db.User.RANK_REGULAR, email='user@example.com'))
with pytest.raises(errors.ValidationError): with pytest.raises(errors.ValidationError):
password_reset_api.post( password_reset_api.post(
context_factory(input={'token': 'bad'}), 'u1') context_factory(input={'token': 'bad'}), 'u1')

View file

@ -8,13 +8,12 @@ from szurubooru.func import posts, tags, snapshots, net
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def inject_config(config_injector): def inject_config(config_injector):
config_injector({ config_injector({
'ranks': ['anonymous', 'regular_user'], 'privileges': {'posts:create': db.User.RANK_REGULAR},
'privileges': {'posts:create': 'regular_user'},
}) })
def test_creating_minimal_posts( def test_creating_minimal_posts(
context_factory, post_factory, user_factory): context_factory, post_factory, user_factory):
auth_user = user_factory(rank='regular_user') auth_user = user_factory(rank=db.User.RANK_REGULAR)
post = post_factory() post = post_factory()
db.session.add(post) db.session.add(post)
db.session.flush() db.session.flush()
@ -60,7 +59,7 @@ def test_creating_minimal_posts(
snapshots.save_entity_creation.assert_called_once_with(post, auth_user) snapshots.save_entity_creation.assert_called_once_with(post, auth_user)
def test_creating_full_posts(context_factory, post_factory, user_factory): def test_creating_full_posts(context_factory, post_factory, user_factory):
auth_user = user_factory(rank='regular_user') auth_user = user_factory(rank=db.User.RANK_REGULAR)
post = post_factory() post = post_factory()
db.session.add(post) db.session.add(post)
db.session.flush() db.session.flush()
@ -107,7 +106,7 @@ def test_creating_full_posts(context_factory, post_factory, user_factory):
def test_creating_from_url_saves_source( def test_creating_from_url_saves_source(
config_injector, context_factory, post_factory, user_factory): config_injector, context_factory, post_factory, user_factory):
auth_user = user_factory(rank='regular_user') auth_user = user_factory(rank=db.User.RANK_REGULAR)
post = post_factory() post = post_factory()
db.session.add(post) db.session.add(post)
db.session.flush() db.session.flush()
@ -119,8 +118,8 @@ def test_creating_from_url_saves_source(
unittest.mock.patch('szurubooru.func.posts.create_post'), \ unittest.mock.patch('szurubooru.func.posts.create_post'), \
unittest.mock.patch('szurubooru.func.posts.update_post_source'): unittest.mock.patch('szurubooru.func.posts.update_post_source'):
config_injector({ config_injector({
'ranks': ['anonymous', 'regular_user'], 'ranks': ['anonymous', db.User.RANK_REGULAR],
'privileges': {'posts:create': 'regular_user'}, 'privileges': {'posts:create': db.User.RANK_REGULAR},
}) })
net.download.return_value = b'content' net.download.return_value = b'content'
posts.create_post.return_value = post posts.create_post.return_value = post
@ -139,7 +138,7 @@ def test_creating_from_url_saves_source(
def test_creating_from_url_with_source_specified( def test_creating_from_url_with_source_specified(
config_injector, context_factory, post_factory, user_factory): config_injector, context_factory, post_factory, user_factory):
auth_user = user_factory(rank='regular_user') auth_user = user_factory(rank=db.User.RANK_REGULAR)
post = post_factory() post = post_factory()
db.session.add(post) db.session.add(post)
db.session.flush() db.session.flush()
@ -151,8 +150,8 @@ def test_creating_from_url_with_source_specified(
unittest.mock.patch('szurubooru.func.posts.create_post'), \ unittest.mock.patch('szurubooru.func.posts.create_post'), \
unittest.mock.patch('szurubooru.func.posts.update_post_source'): unittest.mock.patch('szurubooru.func.posts.update_post_source'):
config_injector({ config_injector({
'ranks': ['anonymous', 'regular_user'], 'ranks': ['anonymous', db.User.RANK_REGULAR],
'privileges': {'posts:create': 'regular_user'}, 'privileges': {'posts:create': db.User.RANK_REGULAR},
}) })
net.download.return_value = b'content' net.download.return_value = b'content'
posts.create_post.return_value = post posts.create_post.return_value = post
@ -182,7 +181,7 @@ def test_trying_to_omit_mandatory_field(context_factory, user_factory, field):
context_factory( context_factory(
input=input, input=input,
files={'content': '...'}, files={'content': '...'},
user=user_factory(rank='regular_user'))) user=user_factory(rank=db.User.RANK_REGULAR)))
def test_trying_to_omit_content(context_factory, user_factory): def test_trying_to_omit_content(context_factory, user_factory):
with pytest.raises(errors.MissingRequiredFileError): with pytest.raises(errors.MissingRequiredFileError):
@ -192,7 +191,7 @@ def test_trying_to_omit_content(context_factory, user_factory):
'safety': 'safe', 'safety': 'safe',
'tags': ['tag1', 'tag2'], 'tags': ['tag1', 'tag2'],
}, },
user=user_factory(rank='regular_user'))) user=user_factory(rank=db.User.RANK_REGULAR)))
def test_trying_to_create_without_privileges(context_factory, user_factory): def test_trying_to_create_without_privileges(context_factory, user_factory):
with pytest.raises(errors.AuthError): with pytest.raises(errors.AuthError):

View file

@ -10,9 +10,8 @@ def test_ctx(
config_injector({ config_injector({
'data_dir': str(tmpdir), 'data_dir': str(tmpdir),
'privileges': { 'privileges': {
'posts:delete': 'regular_user', 'posts:delete': db.User.RANK_REGULAR,
}, },
'ranks': ['anonymous', 'regular_user'],
}) })
ret = util.dotdict() ret = util.dotdict()
ret.context_factory = context_factory ret.context_factory = context_factory
@ -26,7 +25,7 @@ def test_deleting(test_ctx):
db.session.commit() db.session.commit()
result = test_ctx.api.delete( result = test_ctx.api.delete(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
1) 1)
assert result == {} assert result == {}
assert db.session.query(db.Post).count() == 0 assert db.session.query(db.Post).count() == 0
@ -36,7 +35,7 @@ def test_trying_to_delete_non_existing(test_ctx):
with pytest.raises(posts.PostNotFoundError): with pytest.raises(posts.PostNotFoundError):
test_ctx.api.delete( test_ctx.api.delete(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'bad') user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'bad')
def test_trying_to_delete_without_privileges(test_ctx): def test_trying_to_delete_without_privileges(test_ctx):
db.session.add(test_ctx.post_factory(id=1)) db.session.add(test_ctx.post_factory(id=1))

View file

@ -9,11 +9,9 @@ def test_ctx(
config_injector({ config_injector({
'data_dir': str(tmpdir), 'data_dir': str(tmpdir),
'data_url': 'http://example.com', 'data_url': 'http://example.com',
'ranks': ['anonymous', 'regular_user', 'mod'],
'rank_names': {'anonymous': 'Peasant', 'regular_user': 'Lord'},
'privileges': { 'privileges': {
'posts:favorite': 'regular_user', 'posts:favorite': db.User.RANK_REGULAR,
'users:edit:any:email': 'mod', 'users:edit:any:email': db.User.RANK_MODERATOR,
}, },
'thumbnails': {'avatar_width': 200}, 'thumbnails': {'avatar_width': 200},
}) })

View file

@ -10,10 +10,9 @@ def test_ctx(
'data_dir': str(tmpdir), 'data_dir': str(tmpdir),
'data_url': 'http://example.com', 'data_url': 'http://example.com',
'privileges': { 'privileges': {
'posts:feature': 'regular_user', 'posts:feature': db.User.RANK_REGULAR,
'posts:view': 'regular_user', 'posts:view': db.User.RANK_REGULAR,
}, },
'ranks': ['anonymous', 'regular_user'],
}) })
ret = util.dotdict() ret = util.dotdict()
ret.context_factory = context_factory ret.context_factory = context_factory
@ -26,7 +25,7 @@ def test_no_featured_post(test_ctx):
assert posts.try_get_featured_post() is None assert posts.try_get_featured_post() is None
result = test_ctx.api.get( result = test_ctx.api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result == {'post': None, 'snapshots': [], 'comments': []} assert result == {'post': None, 'snapshots': [], 'comments': []}
def test_featuring(test_ctx): def test_featuring(test_ctx):
@ -36,7 +35,7 @@ def test_featuring(test_ctx):
result = test_ctx.api.post( result = test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input={'id': 1}, input={'id': 1},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert posts.try_get_featured_post() is not None assert posts.try_get_featured_post() is not None
assert posts.try_get_featured_post().post_id == 1 assert posts.try_get_featured_post().post_id == 1
assert posts.get_post_by_id(1).is_featured assert posts.get_post_by_id(1).is_featured
@ -46,7 +45,7 @@ def test_featuring(test_ctx):
assert 'comments' in result assert 'comments' in result
result = test_ctx.api.get( result = test_ctx.api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert 'post' in result assert 'post' in result
assert 'id' in result['post'] assert 'id' in result['post']
assert 'snapshots' in result assert 'snapshots' in result
@ -58,12 +57,12 @@ def test_trying_to_feature_the_same_post_twice(test_ctx):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input={'id': 1}, input={'id': 1},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
with pytest.raises(posts.PostAlreadyFeaturedError): with pytest.raises(posts.PostAlreadyFeaturedError):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input={'id': 1}, input={'id': 1},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
def test_featuring_one_post_after_another(test_ctx, fake_datetime): def test_featuring_one_post_after_another(test_ctx, fake_datetime):
db.session.add(test_ctx.post_factory(id=1)) db.session.add(test_ctx.post_factory(id=1))
@ -76,12 +75,12 @@ def test_featuring_one_post_after_another(test_ctx, fake_datetime):
result = test_ctx.api.post( result = test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input={'id': 1}, input={'id': 1},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
with fake_datetime('1998'): with fake_datetime('1998'):
result = test_ctx.api.post( result = test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input={'id': 2}, input={'id': 2},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert posts.try_get_featured_post() is not None assert posts.try_get_featured_post() is not None
assert posts.try_get_featured_post().post_id == 2 assert posts.try_get_featured_post().post_id == 2
assert not posts.get_post_by_id(1).is_featured assert not posts.get_post_by_id(1).is_featured
@ -92,7 +91,7 @@ def test_trying_to_feature_non_existing(test_ctx):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input={'id': 1}, input={'id': 1},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
def test_trying_to_feature_without_privileges(test_ctx): def test_trying_to_feature_without_privileges(test_ctx):
with pytest.raises(errors.AuthError): with pytest.raises(errors.AuthError):

View file

@ -8,9 +8,7 @@ def test_ctx(
config_injector({ config_injector({
'data_dir': str(tmpdir), 'data_dir': str(tmpdir),
'data_url': 'http://example.com', 'data_url': 'http://example.com',
'ranks': ['anonymous', 'regular_user'], 'privileges': {'posts:score': db.User.RANK_REGULAR},
'rank_names': {'anonymous': 'Peasant', 'regular_user': 'Lord'},
'privileges': {'posts:score': 'regular_user'},
'thumbnails': {'avatar_width': 200}, 'thumbnails': {'avatar_width': 200},
}) })
db.session.flush() db.session.flush()

View file

@ -10,12 +10,10 @@ def test_ctx(
'data_dir': str(tmpdir), 'data_dir': str(tmpdir),
'data_url': 'http://example.com', 'data_url': 'http://example.com',
'privileges': { 'privileges': {
'posts:list': 'regular_user', 'posts:list': db.User.RANK_REGULAR,
'posts:view': 'regular_user', 'posts:view': db.User.RANK_REGULAR,
}, },
'thumbnails': {'avatar_width': 200}, 'thumbnails': {'avatar_width': 200},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {'regular_user': 'Peasant'},
}) })
ret = util.dotdict() ret = util.dotdict()
ret.context_factory = context_factory ret.context_factory = context_factory
@ -32,7 +30,7 @@ def test_retrieving_multiple(test_ctx):
result = test_ctx.list_api.get( result = test_ctx.list_api.get(
test_ctx.context_factory( test_ctx.context_factory(
input={'query': '', 'page': 1}, input={'query': '', 'page': 1},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['query'] == '' assert result['query'] == ''
assert result['page'] == 1 assert result['page'] == 1
assert result['pageSize'] == 100 assert result['pageSize'] == 100
@ -41,7 +39,7 @@ def test_retrieving_multiple(test_ctx):
def test_using_special_tokens( def test_using_special_tokens(
test_ctx, config_injector): test_ctx, config_injector):
auth_user = test_ctx.user_factory(rank='regular_user') auth_user = test_ctx.user_factory(rank=db.User.RANK_REGULAR)
post1 = test_ctx.post_factory(id=1) post1 = test_ctx.post_factory(id=1)
post2 = test_ctx.post_factory(id=2) post2 = test_ctx.post_factory(id=2)
post1.favorited_by = [db.PostFavorite( post1.favorited_by = [db.PostFavorite(
@ -81,7 +79,7 @@ def test_retrieving_single(test_ctx):
db.session.add(test_ctx.post_factory(id=1)) db.session.add(test_ctx.post_factory(id=1))
result = test_ctx.detail_api.get( result = test_ctx.detail_api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 1) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 1)
assert 'post' in result assert 'post' in result
assert 'id' in result['post'] assert 'id' in result['post']
assert 'snapshots' in result assert 'snapshots' in result
@ -91,7 +89,7 @@ def test_trying_to_retrieve_single_non_existing(test_ctx):
with pytest.raises(posts.PostNotFoundError): with pytest.raises(posts.PostNotFoundError):
test_ctx.detail_api.get( test_ctx.detail_api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'-') '-')
def test_trying_to_retrieve_single_without_privileges(test_ctx): def test_trying_to_retrieve_single_without_privileges(test_ctx):

View file

@ -8,19 +8,18 @@ from szurubooru.func import posts, tags, snapshots, net
def test_post_updating( def test_post_updating(
config_injector, context_factory, post_factory, user_factory, fake_datetime): config_injector, context_factory, post_factory, user_factory, fake_datetime):
config_injector({ config_injector({
'ranks': ['anonymous', 'regular_user'],
'privileges': { 'privileges': {
'posts:edit:tags': 'regular_user', 'posts:edit:tags': db.User.RANK_REGULAR,
'posts:edit:content': 'regular_user', 'posts:edit:content': db.User.RANK_REGULAR,
'posts:edit:safety': 'regular_user', 'posts:edit:safety': db.User.RANK_REGULAR,
'posts:edit:source': 'regular_user', 'posts:edit:source': db.User.RANK_REGULAR,
'posts:edit:relations': 'regular_user', 'posts:edit:relations': db.User.RANK_REGULAR,
'posts:edit:notes': 'regular_user', 'posts:edit:notes': db.User.RANK_REGULAR,
'posts:edit:flags': 'regular_user', 'posts:edit:flags': db.User.RANK_REGULAR,
'posts:edit:thumbnail': 'regular_user', 'posts:edit:thumbnail': db.User.RANK_REGULAR,
}, },
}) })
auth_user = user_factory(rank='regular_user') auth_user = user_factory(rank=db.User.RANK_REGULAR)
post = post_factory() post = post_factory()
db.session.add(post) db.session.add(post)
db.session.flush() db.session.flush()
@ -76,8 +75,8 @@ def test_post_updating(
def test_uploading_from_url_saves_source( def test_uploading_from_url_saves_source(
config_injector, context_factory, post_factory, user_factory): config_injector, context_factory, post_factory, user_factory):
config_injector({ config_injector({
'ranks': ['anonymous', 'regular_user'], 'ranks': ['anonymous', db.User.RANK_REGULAR],
'privileges': {'posts:edit:content': 'regular_user'}, 'privileges': {'posts:edit:content': db.User.RANK_REGULAR},
}) })
post = post_factory() post = post_factory()
db.session.add(post) db.session.add(post)
@ -92,7 +91,7 @@ def test_uploading_from_url_saves_source(
api.PostDetailApi().put( api.PostDetailApi().put(
context_factory( context_factory(
input={'contentUrl': 'example.com'}, input={'contentUrl': 'example.com'},
user=user_factory(rank='regular_user')), user=user_factory(rank=db.User.RANK_REGULAR)),
post.post_id) post.post_id)
net.download.assert_called_once_with('example.com') net.download.assert_called_once_with('example.com')
posts.update_post_content.assert_called_once_with(post, b'content') posts.update_post_content.assert_called_once_with(post, b'content')
@ -101,10 +100,10 @@ def test_uploading_from_url_saves_source(
def test_uploading_from_url_with_source_specified( def test_uploading_from_url_with_source_specified(
config_injector, context_factory, post_factory, user_factory): config_injector, context_factory, post_factory, user_factory):
config_injector({ config_injector({
'ranks': ['anonymous', 'regular_user'], 'ranks': ['anonymous', db.User.RANK_REGULAR],
'privileges': { 'privileges': {
'posts:edit:content': 'regular_user', 'posts:edit:content': db.User.RANK_REGULAR,
'posts:edit:source': 'regular_user', 'posts:edit:source': db.User.RANK_REGULAR,
}, },
}) })
post = post_factory() post = post_factory()
@ -120,7 +119,7 @@ def test_uploading_from_url_with_source_specified(
api.PostDetailApi().put( api.PostDetailApi().put(
context_factory( context_factory(
input={'contentUrl': 'example.com', 'source': 'example2.com'}, input={'contentUrl': 'example.com', 'source': 'example2.com'},
user=user_factory(rank='regular_user')), user=user_factory(rank=db.User.RANK_REGULAR)),
post.post_id) post.post_id)
net.download.assert_called_once_with('example.com') net.download.assert_called_once_with('example.com')
posts.update_post_content.assert_called_once_with(post, b'content') posts.update_post_content.assert_called_once_with(post, b'content')
@ -131,7 +130,7 @@ def test_trying_to_update_non_existing(context_factory, user_factory):
api.PostDetailApi().put( api.PostDetailApi().put(
context_factory( context_factory(
input='whatever', input='whatever',
user=user_factory(rank='regular_user')), user=user_factory(rank=db.User.RANK_REGULAR)),
1) 1)
@pytest.mark.parametrize('privilege,files,input', [ @pytest.mark.parametrize('privilege,files,input', [
@ -153,8 +152,8 @@ def test_trying_to_create_without_privileges(
input, input,
privilege): privilege):
config_injector({ config_injector({
'ranks': ['anonymous', 'regular_user'], 'ranks': ['anonymous', db.User.RANK_REGULAR],
'privileges': {privilege: 'regular_user'}, 'privileges': {privilege: db.User.RANK_REGULAR},
}) })
post = post_factory() post = post_factory()
db.session.add(post) db.session.add(post)

View file

@ -17,11 +17,9 @@ def snapshot_factory():
def test_ctx(context_factory, config_injector, user_factory): def test_ctx(context_factory, config_injector, user_factory):
config_injector({ config_injector({
'privileges': { 'privileges': {
'snapshots:list': 'regular_user', 'snapshots:list': db.User.RANK_REGULAR,
}, },
'thumbnails': {'avatar_width': 200}, 'thumbnails': {'avatar_width': 200},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {'regular_user': 'Peasant'},
}) })
ret = util.dotdict() ret = util.dotdict()
ret.context_factory = context_factory ret.context_factory = context_factory
@ -36,7 +34,7 @@ def test_retrieving_multiple(test_ctx):
result = test_ctx.api.get( result = test_ctx.api.get(
test_ctx.context_factory( test_ctx.context_factory(
input={'query': '', 'page': 1}, input={'query': '', 'page': 1},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['query'] == '' assert result['query'] == ''
assert result['page'] == 1 assert result['page'] == 1
assert result['pageSize'] == 100 assert result['pageSize'] == 100

View file

@ -8,8 +8,7 @@ def test_ctx(tmpdir, config_injector, context_factory, user_factory):
config_injector({ config_injector({
'data_dir': str(tmpdir), 'data_dir': str(tmpdir),
'tag_category_name_regex': '^[^!]+$', 'tag_category_name_regex': '^[^!]+$',
'ranks': ['anonymous', 'regular_user'], 'privileges': {'tag_categories:create': db.User.RANK_REGULAR},
'privileges': {'tag_categories:create': 'regular_user'},
}) })
ret = util.dotdict() ret = util.dotdict()
ret.context_factory = context_factory ret.context_factory = context_factory
@ -21,7 +20,7 @@ def test_creating_category(test_ctx):
result = test_ctx.api.post( result = test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input={'name': 'meta', 'color': 'black'}, input={'name': 'meta', 'color': 'black'},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['tagCategory'] == {'name': 'meta', 'color': 'black'} assert result['tagCategory'] == {'name': 'meta', 'color': 'black'}
assert len(result['snapshots']) == 1 assert len(result['snapshots']) == 1
category = db.session.query(db.TagCategory).one() category = db.session.query(db.TagCategory).one()
@ -49,7 +48,7 @@ def test_trying_to_pass_invalid_input(test_ctx, input):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input=real_input, input=real_input,
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
@pytest.mark.parametrize('field', ['name', 'color']) @pytest.mark.parametrize('field', ['name', 'color'])
def test_trying_to_omit_mandatory_field(test_ctx, field): def test_trying_to_omit_mandatory_field(test_ctx, field):
@ -62,23 +61,23 @@ def test_trying_to_omit_mandatory_field(test_ctx, field):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input=input, input=input,
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
def test_trying_to_use_existing_name(test_ctx): def test_trying_to_use_existing_name(test_ctx):
result = test_ctx.api.post( result = test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input={'name': 'meta', 'color': 'black'}, input={'name': 'meta', 'color': 'black'},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
with pytest.raises(tag_categories.TagCategoryAlreadyExistsError): with pytest.raises(tag_categories.TagCategoryAlreadyExistsError):
result = test_ctx.api.post( result = test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input={'name': 'meta', 'color': 'black'}, input={'name': 'meta', 'color': 'black'},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
with pytest.raises(tag_categories.TagCategoryAlreadyExistsError): with pytest.raises(tag_categories.TagCategoryAlreadyExistsError):
result = test_ctx.api.post( result = test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input={'name': 'META', 'color': 'black'}, input={'name': 'META', 'color': 'black'},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
def test_trying_to_create_without_privileges(test_ctx): def test_trying_to_create_without_privileges(test_ctx):
with pytest.raises(errors.AuthError): with pytest.raises(errors.AuthError):

View file

@ -15,9 +15,8 @@ def test_ctx(
config_injector({ config_injector({
'data_dir': str(tmpdir), 'data_dir': str(tmpdir),
'privileges': { 'privileges': {
'tag_categories:delete': 'regular_user', 'tag_categories:delete': db.User.RANK_REGULAR,
}, },
'ranks': ['anonymous', 'regular_user'],
}) })
ret = util.dotdict() ret = util.dotdict()
ret.context_factory = context_factory ret.context_factory = context_factory
@ -33,7 +32,7 @@ def test_deleting(test_ctx):
db.session.commit() db.session.commit()
result = test_ctx.api.delete( result = test_ctx.api.delete(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'category') 'category')
assert result == {} assert result == {}
assert db.session.query(db.TagCategory).count() == 1 assert db.session.query(db.TagCategory).count() == 1
@ -50,7 +49,7 @@ def test_trying_to_delete_used(test_ctx, tag_factory):
with pytest.raises(tag_categories.TagCategoryIsInUseError): with pytest.raises(tag_categories.TagCategoryIsInUseError):
test_ctx.api.delete( test_ctx.api.delete(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'category') 'category')
assert db.session.query(db.TagCategory).count() == 1 assert db.session.query(db.TagCategory).count() == 1
@ -60,14 +59,14 @@ def test_trying_to_delete_last(test_ctx, tag_factory):
with pytest.raises(tag_categories.TagCategoryIsInUseError): with pytest.raises(tag_categories.TagCategoryIsInUseError):
result = test_ctx.api.delete( result = test_ctx.api.delete(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'root') 'root')
def test_trying_to_delete_non_existing(test_ctx): def test_trying_to_delete_non_existing(test_ctx):
with pytest.raises(tag_categories.TagCategoryNotFoundError): with pytest.raises(tag_categories.TagCategoryNotFoundError):
test_ctx.api.delete( test_ctx.api.delete(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'bad') user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'bad')
def test_trying_to_delete_without_privileges(test_ctx): def test_trying_to_delete_without_privileges(test_ctx):
db.session.add(test_ctx.tag_category_factory(name='category')) db.session.add(test_ctx.tag_category_factory(name='category'))

View file

@ -8,12 +8,10 @@ def test_ctx(
context_factory, config_injector, user_factory, tag_category_factory): context_factory, config_injector, user_factory, tag_category_factory):
config_injector({ config_injector({
'privileges': { 'privileges': {
'tag_categories:list': 'regular_user', 'tag_categories:list': db.User.RANK_REGULAR,
'tag_categories:view': 'regular_user', 'tag_categories:view': db.User.RANK_REGULAR,
}, },
'thumbnails': {'avatar_width': 200}, 'thumbnails': {'avatar_width': 200},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {'regular_user': 'Peasant'},
}) })
ret = util.dotdict() ret = util.dotdict()
ret.context_factory = context_factory ret.context_factory = context_factory
@ -30,14 +28,14 @@ def test_retrieving_multiple(test_ctx):
]) ])
result = test_ctx.list_api.get( result = test_ctx.list_api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert [cat['name'] for cat in result['results']] == ['c1', 'c2'] assert [cat['name'] for cat in result['results']] == ['c1', 'c2']
def test_retrieving_single(test_ctx): def test_retrieving_single(test_ctx):
db.session.add(test_ctx.tag_category_factory(name='cat')) db.session.add(test_ctx.tag_category_factory(name='cat'))
result = test_ctx.detail_api.get( result = test_ctx.detail_api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'cat') 'cat')
assert result == { assert result == {
'tagCategory': { 'tagCategory': {
@ -51,7 +49,7 @@ def test_trying_to_retrieve_single_non_existing(test_ctx):
with pytest.raises(tag_categories.TagCategoryNotFoundError): with pytest.raises(tag_categories.TagCategoryNotFoundError):
test_ctx.detail_api.get( test_ctx.detail_api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'-') '-')
def test_trying_to_retrieve_single_without_privileges(test_ctx): def test_trying_to_retrieve_single_without_privileges(test_ctx):

View file

@ -13,10 +13,9 @@ def test_ctx(
config_injector({ config_injector({
'data_dir': str(tmpdir), 'data_dir': str(tmpdir),
'tag_category_name_regex': '^[^!]*$', 'tag_category_name_regex': '^[^!]*$',
'ranks': ['anonymous', 'regular_user'],
'privileges': { 'privileges': {
'tag_categories:edit:name': 'regular_user', 'tag_categories:edit:name': db.User.RANK_REGULAR,
'tag_categories:edit:color': 'regular_user', 'tag_categories:edit:color': db.User.RANK_REGULAR,
}, },
}) })
ret = util.dotdict() ret = util.dotdict()
@ -36,7 +35,7 @@ def test_simple_updating(test_ctx):
'name': 'changed', 'name': 'changed',
'color': 'white', 'color': 'white',
}, },
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'name') 'name')
assert result['tagCategory'] == { assert result['tagCategory'] == {
'name': 'changed', 'name': 'changed',
@ -64,7 +63,7 @@ def test_trying_to_pass_invalid_input(test_ctx, input):
test_ctx.api.put( test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(
input=input, input=input,
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'meta') 'meta')
@pytest.mark.parametrize('field', ['name', 'color']) @pytest.mark.parametrize('field', ['name', 'color'])
@ -79,7 +78,7 @@ def test_omitting_optional_field(test_ctx, field):
result = test_ctx.api.put( result = test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(
input=input, input=input,
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'name') 'name')
assert result is not None assert result is not None
@ -88,7 +87,7 @@ def test_trying_to_update_non_existing(test_ctx):
test_ctx.api.put( test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(
input={'name': ['dummy']}, input={'name': ['dummy']},
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'bad') 'bad')
@pytest.mark.parametrize('new_name', ['cat', 'CAT']) @pytest.mark.parametrize('new_name', ['cat', 'CAT'])
@ -98,7 +97,7 @@ def test_reusing_own_name(test_ctx, new_name):
result = test_ctx.api.put( result = test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(
input={'name': new_name}, input={'name': new_name},
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'cat') 'cat')
assert result['tagCategory']['name'] == new_name assert result['tagCategory']['name'] == new_name
category = tag_categories.get_category_by_name('cat') category = tag_categories.get_category_by_name('cat')
@ -114,7 +113,7 @@ def test_trying_to_use_existing_name(test_ctx, dup_name):
test_ctx.api.put( test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(
input={'name': dup_name}, input={'name': dup_name},
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'cat2') 'cat2')
@pytest.mark.parametrize('input', [ @pytest.mark.parametrize('input', [

View file

@ -15,8 +15,7 @@ def test_ctx(
'data_dir': str(tmpdir), 'data_dir': str(tmpdir),
'tag_name_regex': '^[^!]*$', 'tag_name_regex': '^[^!]*$',
'tag_category_name_regex': '^[^!]*$', 'tag_category_name_regex': '^[^!]*$',
'ranks': ['anonymous', 'regular_user'], 'privileges': {'tags:create': db.User.RANK_REGULAR},
'privileges': {'tags:create': 'regular_user'},
}) })
db.session.add_all([ db.session.add_all([
db.TagCategory(name) for name in ['meta', 'character', 'copyright']]) db.TagCategory(name) for name in ['meta', 'character', 'copyright']])
@ -38,7 +37,7 @@ def test_creating_simple_tags(test_ctx, fake_datetime):
'suggestions': [], 'suggestions': [],
'implications': [], 'implications': [],
}, },
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['tag'] == { assert result['tag'] == {
'names': ['tag1', 'tag2'], 'names': ['tag1', 'tag2'],
'category': 'meta', 'category': 'meta',
@ -99,7 +98,7 @@ def test_trying_to_omit_mandatory_field(test_ctx, field):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input=input, input=input,
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
@pytest.mark.parametrize('field', ['implications', 'suggestions']) @pytest.mark.parametrize('field', ['implications', 'suggestions'])
def test_omitting_optional_field(test_ctx, field): def test_omitting_optional_field(test_ctx, field):
@ -113,7 +112,7 @@ def test_omitting_optional_field(test_ctx, field):
result = test_ctx.api.post( result = test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input=input, input=input,
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result is not None assert result is not None
def test_duplicating_names(test_ctx): def test_duplicating_names(test_ctx):
@ -125,7 +124,7 @@ def test_duplicating_names(test_ctx):
'suggestions': [], 'suggestions': [],
'implications': [], 'implications': [],
}, },
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['tag']['names'] == ['tag1'] assert result['tag']['names'] == ['tag1']
assert result['tag']['category'] == 'meta' assert result['tag']['category'] == 'meta'
tag = tags.get_tag_by_name('tag1') tag = tags.get_tag_by_name('tag1')
@ -146,7 +145,7 @@ def test_trying_to_use_existing_name(test_ctx):
'suggestions': [], 'suggestions': [],
'implications': [], 'implications': [],
}, },
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
with pytest.raises(tags.TagAlreadyExistsError): with pytest.raises(tags.TagAlreadyExistsError):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
@ -156,7 +155,7 @@ def test_trying_to_use_existing_name(test_ctx):
'suggestions': [], 'suggestions': [],
'implications': [], 'implications': [],
}, },
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert tags.try_get_tag_by_name('unused') is None assert tags.try_get_tag_by_name('unused') is None
def test_creating_new_category(test_ctx): def test_creating_new_category(test_ctx):
@ -167,7 +166,7 @@ def test_creating_new_category(test_ctx):
'category': 'new', 'category': 'new',
'suggestions': [], 'suggestions': [],
'implications': [], 'implications': [],
}, user=test_ctx.user_factory(rank='regular_user'))) }, user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert tag_categories.try_get_category_by_name('new') is not None assert tag_categories.try_get_category_by_name('new') is not None
@pytest.mark.parametrize('input,expected_suggestions,expected_implications', [ @pytest.mark.parametrize('input,expected_suggestions,expected_implications', [
@ -204,7 +203,7 @@ def test_creating_new_suggestions_and_implications(
test_ctx, input, expected_suggestions, expected_implications): test_ctx, input, expected_suggestions, expected_implications):
result = test_ctx.api.post( result = test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input=input, user=test_ctx.user_factory(rank='regular_user'))) input=input, user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['tag']['suggestions'] == expected_suggestions assert result['tag']['suggestions'] == expected_suggestions
assert result['tag']['implications'] == expected_implications assert result['tag']['implications'] == expected_implications
tag = tags.get_tag_by_name('main') tag = tags.get_tag_by_name('main')
@ -227,7 +226,7 @@ def test_reusing_suggestions_and_implications(test_ctx):
'suggestions': ['TAG2'], 'suggestions': ['TAG2'],
'implications': ['tag1'], 'implications': ['tag1'],
}, },
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
# NOTE: it should export only the first name # NOTE: it should export only the first name
assert result['tag']['suggestions'] == ['tag1'] assert result['tag']['suggestions'] == ['tag1']
assert result['tag']['implications'] == ['tag1'] assert result['tag']['implications'] == ['tag1']
@ -254,7 +253,7 @@ def test_tag_trying_to_relate_to_itself(test_ctx, input):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input=input, input=input,
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert tags.try_get_tag_by_name('tag') is None assert tags.try_get_tag_by_name('tag') is None
def test_trying_to_create_tag_without_privileges(test_ctx): def test_trying_to_create_tag_without_privileges(test_ctx):

View file

@ -10,9 +10,8 @@ def test_ctx(
config_injector({ config_injector({
'data_dir': str(tmpdir), 'data_dir': str(tmpdir),
'privileges': { 'privileges': {
'tags:delete': 'regular_user', 'tags:delete': db.User.RANK_REGULAR,
}, },
'ranks': ['anonymous', 'regular_user'],
}) })
ret = util.dotdict() ret = util.dotdict()
ret.context_factory = context_factory ret.context_factory = context_factory
@ -26,7 +25,7 @@ def test_deleting(test_ctx):
db.session.commit() db.session.commit()
result = test_ctx.api.delete( result = test_ctx.api.delete(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag') 'tag')
assert result == {} assert result == {}
assert db.session.query(db.Tag).count() == 0 assert db.session.query(db.Tag).count() == 0
@ -41,7 +40,7 @@ def test_trying_to_delete_used(test_ctx, post_factory):
with pytest.raises(tags.TagIsInUseError): with pytest.raises(tags.TagIsInUseError):
test_ctx.api.delete( test_ctx.api.delete(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag') 'tag')
assert db.session.query(db.Tag).count() == 1 assert db.session.query(db.Tag).count() == 1
@ -49,7 +48,7 @@ def test_trying_to_delete_non_existing(test_ctx):
with pytest.raises(tags.TagNotFoundError): with pytest.raises(tags.TagNotFoundError):
test_ctx.api.delete( test_ctx.api.delete(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'bad') user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'bad')
def test_trying_to_delete_without_privileges(test_ctx): def test_trying_to_delete_without_privileges(test_ctx):
db.session.add(test_ctx.tag_factory(names=['tag'])) db.session.add(test_ctx.tag_factory(names=['tag']))

View file

@ -9,9 +9,8 @@ def test_ctx(
tmpdir, config_injector, context_factory, user_factory, tag_factory): tmpdir, config_injector, context_factory, user_factory, tag_factory):
config_injector({ config_injector({
'data_dir': str(tmpdir), 'data_dir': str(tmpdir),
'ranks': ['anonymous', 'regular_user'],
'privileges': { 'privileges': {
'tags:merge': 'regular_user', 'tags:merge': db.User.RANK_REGULAR,
}, },
}) })
ret = util.dotdict() ret = util.dotdict()
@ -33,7 +32,7 @@ def test_merging_without_usages(test_ctx, fake_datetime):
'remove': 'source', 'remove': 'source',
'merge-to': 'target', 'merge-to': 'target',
}, },
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['tag'] == { assert result['tag'] == {
'names': ['target'], 'names': ['target'],
'category': 'meta', 'category': 'meta',
@ -69,7 +68,7 @@ def test_merging_with_usages(test_ctx, fake_datetime, post_factory):
'remove': 'source', 'remove': 'source',
'merge-to': 'target', 'merge-to': 'target',
}, },
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert tags.try_get_tag_by_name('source') is None assert tags.try_get_tag_by_name('source') is None
assert tags.get_tag_by_name('target').post_count == 1 assert tags.get_tag_by_name('target').post_count == 1
@ -96,7 +95,7 @@ def test_trying_to_pass_invalid_input(test_ctx, input, expected_exception):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input=real_input, input=real_input,
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
@pytest.mark.parametrize( @pytest.mark.parametrize(
'field', ['remove', 'merge-to']) 'field', ['remove', 'merge-to'])
@ -115,7 +114,7 @@ def test_trying_to_omit_mandatory_field(test_ctx, field):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input=input, input=input,
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
def test_trying_to_merge_non_existing(test_ctx): def test_trying_to_merge_non_existing(test_ctx):
db.session.add(test_ctx.tag_factory(names=['good'], category_name='meta')) db.session.add(test_ctx.tag_factory(names=['good'], category_name='meta'))
@ -124,12 +123,12 @@ def test_trying_to_merge_non_existing(test_ctx):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input={'remove': 'good', 'merge-to': 'bad'}, input={'remove': 'good', 'merge-to': 'bad'},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
with pytest.raises(tags.TagNotFoundError): with pytest.raises(tags.TagNotFoundError):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input={'remove': 'bad', 'merge-to': 'good'}, input={'remove': 'bad', 'merge-to': 'good'},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
def test_trying_to_merge_to_itself(test_ctx): def test_trying_to_merge_to_itself(test_ctx):
db.session.add(test_ctx.tag_factory(names=['good'], category_name='meta')) db.session.add(test_ctx.tag_factory(names=['good'], category_name='meta'))
@ -138,7 +137,7 @@ def test_trying_to_merge_to_itself(test_ctx):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input={'remove': 'good', 'merge-to': 'good'}, input={'remove': 'good', 'merge-to': 'good'},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
@pytest.mark.parametrize('input', [ @pytest.mark.parametrize('input', [
{'names': 'whatever'}, {'names': 'whatever'},

View file

@ -7,12 +7,10 @@ from szurubooru.func import util, tags
def test_ctx(context_factory, config_injector, user_factory, tag_factory): def test_ctx(context_factory, config_injector, user_factory, tag_factory):
config_injector({ config_injector({
'privileges': { 'privileges': {
'tags:list': 'regular_user', 'tags:list': db.User.RANK_REGULAR,
'tags:view': 'regular_user', 'tags:view': db.User.RANK_REGULAR,
}, },
'thumbnails': {'avatar_width': 200}, 'thumbnails': {'avatar_width': 200},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {'regular_user': 'Peasant'},
}) })
ret = util.dotdict() ret = util.dotdict()
ret.context_factory = context_factory ret.context_factory = context_factory
@ -29,7 +27,7 @@ def test_retrieving_multiple(test_ctx):
result = test_ctx.list_api.get( result = test_ctx.list_api.get(
test_ctx.context_factory( test_ctx.context_factory(
input={'query': '', 'page': 1}, input={'query': '', 'page': 1},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['query'] == '' assert result['query'] == ''
assert result['page'] == 1 assert result['page'] == 1
assert result['pageSize'] == 100 assert result['pageSize'] == 100
@ -47,7 +45,7 @@ def test_retrieving_single(test_ctx):
db.session.add(test_ctx.tag_factory(names=['tag'])) db.session.add(test_ctx.tag_factory(names=['tag']))
result = test_ctx.detail_api.get( result = test_ctx.detail_api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag') 'tag')
assert result == { assert result == {
'tag': { 'tag': {
@ -66,7 +64,7 @@ def test_trying_to_retrieve_single_non_existing(test_ctx):
with pytest.raises(tags.TagNotFoundError): with pytest.raises(tags.TagNotFoundError):
test_ctx.detail_api.get( test_ctx.detail_api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'-') '-')
def test_trying_to_retrieve_single_without_privileges(test_ctx): def test_trying_to_retrieve_single_without_privileges(test_ctx):

View file

@ -16,10 +16,9 @@ def test_ctx(
context_factory, config_injector, user_factory, tag_factory, post_factory): context_factory, config_injector, user_factory, tag_factory, post_factory):
config_injector({ config_injector({
'privileges': { 'privileges': {
'tags:view': 'regular_user', 'tags:view': db.User.RANK_REGULAR,
}, },
'thumbnails': {'avatar_width': 200}, 'thumbnails': {'avatar_width': 200},
'ranks': ['anonymous', 'regular_user'],
}) })
ret = util.dotdict() ret = util.dotdict()
ret.context_factory = context_factory ret.context_factory = context_factory
@ -33,7 +32,7 @@ def test_unused(test_ctx):
db.session.add(test_ctx.tag_factory(names=['tag'])) db.session.add(test_ctx.tag_factory(names=['tag']))
result = test_ctx.api.get( result = test_ctx.api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'tag') user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'tag')
assert_results(result, {}) assert_results(result, {})
def test_used_alone(test_ctx): def test_used_alone(test_ctx):
@ -43,7 +42,7 @@ def test_used_alone(test_ctx):
db.session.add_all([post, tag]) db.session.add_all([post, tag])
result = test_ctx.api.get( result = test_ctx.api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'tag') user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'tag')
assert_results(result, {}) assert_results(result, {})
def test_used_with_others(test_ctx): def test_used_with_others(test_ctx):
@ -54,11 +53,11 @@ def test_used_with_others(test_ctx):
db.session.add_all([post, tag1, tag2]) db.session.add_all([post, tag1, tag2])
result = test_ctx.api.get( result = test_ctx.api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'tag1') user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'tag1')
assert_results(result, {'tag2': 1}) assert_results(result, {'tag2': 1})
result = test_ctx.api.get( result = test_ctx.api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'tag2') user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'tag2')
assert_results(result, {'tag1': 1}) assert_results(result, {'tag1': 1})
def test_used_with_multiple_others(test_ctx): def test_used_with_multiple_others(test_ctx):
@ -72,22 +71,22 @@ def test_used_with_multiple_others(test_ctx):
db.session.add_all([post1, post2, tag1, tag2, tag3]) db.session.add_all([post1, post2, tag1, tag2, tag3])
result = test_ctx.api.get( result = test_ctx.api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'tag1') user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'tag1')
assert_results(result, {'tag2': 1, 'tag3': 2}) assert_results(result, {'tag2': 1, 'tag3': 2})
result = test_ctx.api.get( result = test_ctx.api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'tag2') user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'tag2')
assert_results(result, {'tag1': 1, 'tag3': 1}) assert_results(result, {'tag1': 1, 'tag3': 1})
result = test_ctx.api.get( result = test_ctx.api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'tag3') user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'tag3')
assert_results(result, {'tag1': 2, 'tag2': 1}) assert_results(result, {'tag1': 2, 'tag2': 1})
def test_trying_to_retrieve_non_existing(test_ctx): def test_trying_to_retrieve_non_existing(test_ctx):
with pytest.raises(tags.TagNotFoundError): with pytest.raises(tags.TagNotFoundError):
test_ctx.api.get( test_ctx.api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), '-') user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), '-')
def test_trying_to_retrieve_without_privileges(test_ctx): def test_trying_to_retrieve_without_privileges(test_ctx):
with pytest.raises(errors.AuthError): with pytest.raises(errors.AuthError):

View file

@ -15,12 +15,11 @@ def test_ctx(
'data_dir': str(tmpdir), 'data_dir': str(tmpdir),
'tag_name_regex': '^[^!]*$', 'tag_name_regex': '^[^!]*$',
'tag_category_name_regex': '^[^!]*$', 'tag_category_name_regex': '^[^!]*$',
'ranks': ['anonymous', 'regular_user'],
'privileges': { 'privileges': {
'tags:edit:names': 'regular_user', 'tags:edit:names': db.User.RANK_REGULAR,
'tags:edit:category': 'regular_user', 'tags:edit:category': db.User.RANK_REGULAR,
'tags:edit:suggestions': 'regular_user', 'tags:edit:suggestions': db.User.RANK_REGULAR,
'tags:edit:implications': 'regular_user', 'tags:edit:implications': db.User.RANK_REGULAR,
}, },
}) })
db.session.add_all([ db.session.add_all([
@ -44,7 +43,7 @@ def test_simple_updating(test_ctx, fake_datetime):
'names': ['tag3'], 'names': ['tag3'],
'category': 'character', 'category': 'character',
}, },
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag1') 'tag1')
assert result['tag'] == { assert result['tag'] == {
'names': ['tag3'], 'names': ['tag3'],
@ -86,7 +85,7 @@ def test_trying_to_pass_invalid_input(test_ctx, input, expected_exception):
test_ctx.api.put( test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(
input=input, input=input,
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag1') 'tag1')
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -104,7 +103,7 @@ def test_omitting_optional_field(test_ctx, field):
result = test_ctx.api.put( result = test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(
input=input, input=input,
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag') 'tag')
assert result is not None assert result is not None
@ -113,7 +112,7 @@ def test_trying_to_update_non_existing(test_ctx):
test_ctx.api.put( test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(
input={'names': ['dummy']}, input={'names': ['dummy']},
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag1') 'tag1')
@pytest.mark.parametrize('dup_name', ['tag1', 'TAG1']) @pytest.mark.parametrize('dup_name', ['tag1', 'TAG1'])
@ -124,7 +123,7 @@ def test_reusing_own_name(test_ctx, dup_name):
result = test_ctx.api.put( result = test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(
input={'names': [dup_name, 'tag3']}, input={'names': [dup_name, 'tag3']},
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag1') 'tag1')
assert result['tag']['names'] == ['tag1', 'tag3'] assert result['tag']['names'] == ['tag1', 'tag3']
assert tags.try_get_tag_by_name('tag2') is None assert tags.try_get_tag_by_name('tag2') is None
@ -139,7 +138,7 @@ def test_duplicating_names(test_ctx):
result = test_ctx.api.put( result = test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(
input={'names': ['tag3', 'TAG3']}, input={'names': ['tag3', 'TAG3']},
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag1') 'tag1')
assert result['tag']['names'] == ['tag3'] assert result['tag']['names'] == ['tag3']
assert tags.try_get_tag_by_name('tag1') is None assert tags.try_get_tag_by_name('tag1') is None
@ -158,7 +157,7 @@ def test_trying_to_use_existing_name(test_ctx, dup_name):
test_ctx.api.put( test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(
input={'names': [dup_name]}, input={'names': [dup_name]},
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag3') 'tag3')
@pytest.mark.parametrize('input,expected_suggestions,expected_implications', [ @pytest.mark.parametrize('input,expected_suggestions,expected_implications', [
@ -190,7 +189,7 @@ def test_updating_new_suggestions_and_implications(
db.session.commit() db.session.commit()
result = test_ctx.api.put( result = test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(
input=input, user=test_ctx.user_factory(rank='regular_user')), input=input, user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'main') 'main')
assert result['tag']['suggestions'] == expected_suggestions assert result['tag']['suggestions'] == expected_suggestions
assert result['tag']['implications'] == expected_implications assert result['tag']['implications'] == expected_implications
@ -215,7 +214,7 @@ def test_reusing_suggestions_and_implications(test_ctx):
'suggestions': ['TAG2'], 'suggestions': ['TAG2'],
'implications': ['tag1'], 'implications': ['tag1'],
}, },
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag4') 'tag4')
# NOTE: it should export only the first name # NOTE: it should export only the first name
assert result['tag']['suggestions'] == ['tag1'] assert result['tag']['suggestions'] == ['tag1']
@ -244,7 +243,7 @@ def test_trying_to_relate_tag_to_itself(test_ctx, input):
with pytest.raises(tags.InvalidTagRelationError): with pytest.raises(tags.InvalidTagRelationError):
test_ctx.api.put( test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(
input=input, user=test_ctx.user_factory(rank='regular_user')), input=input, user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'tag1') 'tag1')
@pytest.mark.parametrize('input', [ @pytest.mark.parametrize('input', [

View file

@ -14,10 +14,8 @@ def test_ctx(config_injector, context_factory, user_factory):
'secret': '', 'secret': '',
'user_name_regex': '[^!]{3,}', 'user_name_regex': '[^!]{3,}',
'password_regex': '[^!]{3,}', 'password_regex': '[^!]{3,}',
'default_rank': 'regular_user', 'default_rank': db.User.RANK_REGULAR,
'thumbnails': {'avatar_width': 200, 'avatar_height': 200}, 'thumbnails': {'avatar_width': 200, 'avatar_height': 200},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {},
'privileges': {'users:create': 'anonymous'}, 'privileges': {'users:create': 'anonymous'},
}) })
ret = util.dotdict() ret = util.dotdict()
@ -35,7 +33,7 @@ def test_creating_user(test_ctx, fake_datetime):
'email': 'asd@asd.asd', 'email': 'asd@asd.asd',
'password': 'oks', 'password': 'oks',
}, },
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result == { assert result == {
'user': { 'user': {
'avatarStyle': 'gravatar', 'avatarStyle': 'gravatar',
@ -44,15 +42,14 @@ def test_creating_user(test_ctx, fake_datetime):
'creationTime': datetime.datetime(1969, 2, 12), 'creationTime': datetime.datetime(1969, 2, 12),
'lastLoginTime': None, 'lastLoginTime': None,
'name': 'chewie1', 'name': 'chewie1',
'rank': 'admin', 'rank': 'administrator',
'rankName': 'Unknown',
'email': 'asd@asd.asd', 'email': 'asd@asd.asd',
} }
} }
user = users.get_user_by_name('chewie1') user = users.get_user_by_name('chewie1')
assert user.name == 'chewie1' assert user.name == 'chewie1'
assert user.email == 'asd@asd.asd' assert user.email == 'asd@asd.asd'
assert user.rank == 'admin' assert user.rank == db.User.RANK_ADMINISTRATOR
assert auth.is_valid_password(user, 'oks') is True assert auth.is_valid_password(user, 'oks') is True
assert auth.is_valid_password(user, 'invalid') is False assert auth.is_valid_password(user, 'invalid') is False
@ -73,12 +70,12 @@ def test_first_user_becomes_admin_others_not(test_ctx):
'password': 'sok', 'password': 'sok',
}, },
user=test_ctx.user_factory(rank='anonymous'))) user=test_ctx.user_factory(rank='anonymous')))
assert result1['user']['rank'] == 'admin' assert result1['user']['rank'] == 'administrator'
assert result2['user']['rank'] == 'regular_user' assert result2['user']['rank'] == 'regular'
first_user = users.get_user_by_name('chewie1') first_user = users.get_user_by_name('chewie1')
other_user = users.get_user_by_name('chewie2') other_user = users.get_user_by_name('chewie2')
assert first_user.rank == 'admin' assert first_user.rank == db.User.RANK_ADMINISTRATOR
assert other_user.rank == 'regular_user' assert other_user.rank == db.User.RANK_REGULAR
def test_first_user_does_not_become_admin_if_they_dont_wish_so(test_ctx): def test_first_user_does_not_become_admin_if_they_dont_wish_so(test_ctx):
result = test_ctx.api.post( result = test_ctx.api.post(
@ -87,10 +84,10 @@ def test_first_user_does_not_become_admin_if_they_dont_wish_so(test_ctx):
'name': 'chewie1', 'name': 'chewie1',
'email': 'asd@asd.asd', 'email': 'asd@asd.asd',
'password': 'oks', 'password': 'oks',
'rank': 'regular_user', 'rank': 'regular',
}, },
user=test_ctx.user_factory(rank='anonymous'))) user=test_ctx.user_factory(rank='anonymous')))
assert result['user']['rank'] == 'regular_user' assert result['user']['rank'] == 'regular'
def test_trying_to_become_someone_else(test_ctx): def test_trying_to_become_someone_else(test_ctx):
test_ctx.api.post( test_ctx.api.post(
@ -100,7 +97,7 @@ def test_trying_to_become_someone_else(test_ctx):
'email': 'asd@asd.asd', 'email': 'asd@asd.asd',
'password': 'oks', 'password': 'oks',
}, },
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
with pytest.raises(users.UserAlreadyExistsError): with pytest.raises(users.UserAlreadyExistsError):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
@ -109,7 +106,7 @@ def test_trying_to_become_someone_else(test_ctx):
'email': 'asd@asd.asd', 'email': 'asd@asd.asd',
'password': 'oks', 'password': 'oks',
}, },
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
with pytest.raises(users.UserAlreadyExistsError): with pytest.raises(users.UserAlreadyExistsError):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
@ -118,7 +115,7 @@ def test_trying_to_become_someone_else(test_ctx):
'email': 'asd@asd.asd', 'email': 'asd@asd.asd',
'password': 'oks', 'password': 'oks',
}, },
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
@pytest.mark.parametrize('input,expected_exception', [ @pytest.mark.parametrize('input,expected_exception', [
({'name': None}, users.InvalidUserNameError), ({'name': None}, users.InvalidUserNameError),
@ -150,7 +147,8 @@ def test_trying_to_pass_invalid_input(test_ctx, input, expected_exception):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input=real_input, input=real_input,
user=test_ctx.user_factory(name='u1', rank='admin'))) user=test_ctx.user_factory(
name='u1', rank=db.User.RANK_ADMINISTRATOR)))
@pytest.mark.parametrize('field', ['name', 'password']) @pytest.mark.parametrize('field', ['name', 'password'])
def test_trying_to_omit_mandatory_field(test_ctx, field): def test_trying_to_omit_mandatory_field(test_ctx, field):
@ -164,7 +162,7 @@ def test_trying_to_omit_mandatory_field(test_ctx, field):
test_ctx.api.post( test_ctx.api.post(
test_ctx.context_factory( test_ctx.context_factory(
input=input, input=input,
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
@pytest.mark.parametrize('field', ['rank', 'email', 'avatarStyle']) @pytest.mark.parametrize('field', ['rank', 'email', 'avatarStyle'])
def test_omitting_optional_field(test_ctx, tmpdir, field): def test_omitting_optional_field(test_ctx, tmpdir, field):
@ -174,7 +172,7 @@ def test_omitting_optional_field(test_ctx, tmpdir, field):
'name': 'chewie', 'name': 'chewie',
'email': 'asd@asd.asd', 'email': 'asd@asd.asd',
'password': 'oks', 'password': 'oks',
'rank': 'mod', 'rank': 'moderator',
'avatarStyle': 'manual', 'avatarStyle': 'manual',
} }
del input[field] del input[field]
@ -182,33 +180,33 @@ def test_omitting_optional_field(test_ctx, tmpdir, field):
test_ctx.context_factory( test_ctx.context_factory(
input=input, input=input,
files={'avatar': EMPTY_PIXEL}, files={'avatar': EMPTY_PIXEL},
user=test_ctx.user_factory(rank='mod'))) user=test_ctx.user_factory(rank=db.User.RANK_MODERATOR)))
assert result is not None assert result is not None
def test_mods_trying_to_become_admin(test_ctx): def test_mods_trying_to_become_admin(test_ctx):
user1 = test_ctx.user_factory(name='u1', rank='mod') user1 = test_ctx.user_factory(name='u1', rank=db.User.RANK_MODERATOR)
user2 = test_ctx.user_factory(name='u2', rank='mod') user2 = test_ctx.user_factory(name='u2', rank=db.User.RANK_MODERATOR)
db.session.add_all([user1, user2]) db.session.add_all([user1, user2])
context = test_ctx.context_factory(input={ context = test_ctx.context_factory(input={
'name': 'chewie', 'name': 'chewie',
'email': 'asd@asd.asd', 'email': 'asd@asd.asd',
'password': 'oks', 'password': 'oks',
'rank': 'admin', 'rank': 'administrator',
}, user=user1) }, user=user1)
with pytest.raises(errors.AuthError): with pytest.raises(errors.AuthError):
test_ctx.api.post(context) test_ctx.api.post(context)
def test_admin_creating_mod_account(test_ctx): def test_admin_creating_mod_account(test_ctx):
user = test_ctx.user_factory(rank='admin') user = test_ctx.user_factory(rank=db.User.RANK_ADMINISTRATOR)
db.session.add(user) db.session.add(user)
context = test_ctx.context_factory(input={ context = test_ctx.context_factory(input={
'name': 'chewie', 'name': 'chewie',
'email': 'asd@asd.asd', 'email': 'asd@asd.asd',
'password': 'oks', 'password': 'oks',
'rank': 'mod', 'rank': 'moderator',
}, user=user) }, user=user)
result = test_ctx.api.post(context) result = test_ctx.api.post(context)
assert result['user']['rank'] == 'mod' assert result['user']['rank'] == 'moderator'
def test_uploading_avatar(test_ctx, tmpdir): def test_uploading_avatar(test_ctx, tmpdir):
config.config['data_dir'] = str(tmpdir.mkdir('data')) config.config['data_dir'] = str(tmpdir.mkdir('data'))
@ -222,7 +220,7 @@ def test_uploading_avatar(test_ctx, tmpdir):
'avatarStyle': 'manual', 'avatarStyle': 'manual',
}, },
files={'avatar': EMPTY_PIXEL}, files={'avatar': EMPTY_PIXEL},
user=test_ctx.user_factory(rank='mod'))) user=test_ctx.user_factory(rank=db.User.RANK_MODERATOR)))
user = users.get_user_by_name('chewie') user = users.get_user_by_name('chewie')
assert user.avatar_style == user.AVATAR_MANUAL assert user.avatar_style == user.AVATAR_MANUAL
assert response['user']['avatarUrl'] == \ assert response['user']['avatarUrl'] == \

View file

@ -7,10 +7,9 @@ from szurubooru.func import util, users
def test_ctx(config_injector, context_factory, user_factory): def test_ctx(config_injector, context_factory, user_factory):
config_injector({ config_injector({
'privileges': { 'privileges': {
'users:delete:self': 'regular_user', 'users:delete:self': db.User.RANK_REGULAR,
'users:delete:any': 'mod', 'users:delete:any': db.User.RANK_MODERATOR,
}, },
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
}) })
ret = util.dotdict() ret = util.dotdict()
ret.context_factory = context_factory ret.context_factory = context_factory
@ -19,7 +18,7 @@ def test_ctx(config_injector, context_factory, user_factory):
return ret return ret
def test_deleting_oneself(test_ctx): def test_deleting_oneself(test_ctx):
user = test_ctx.user_factory(name='u', rank='regular_user') user = test_ctx.user_factory(name='u', rank=db.User.RANK_REGULAR)
db.session.add(user) db.session.add(user)
db.session.commit() db.session.commit()
result = test_ctx.api.delete(test_ctx.context_factory(user=user), 'u') result = test_ctx.api.delete(test_ctx.context_factory(user=user), 'u')
@ -27,16 +26,16 @@ def test_deleting_oneself(test_ctx):
assert db.session.query(db.User).count() == 0 assert db.session.query(db.User).count() == 0
def test_deleting_someone_else(test_ctx): def test_deleting_someone_else(test_ctx):
user1 = test_ctx.user_factory(name='u1', rank='regular_user') user1 = test_ctx.user_factory(name='u1', rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(name='u2', rank='mod') user2 = test_ctx.user_factory(name='u2', rank=db.User.RANK_MODERATOR)
db.session.add_all([user1, user2]) db.session.add_all([user1, user2])
db.session.commit() db.session.commit()
test_ctx.api.delete(test_ctx.context_factory(user=user2), 'u1') test_ctx.api.delete(test_ctx.context_factory(user=user2), 'u1')
assert db.session.query(db.User).count() == 1 assert db.session.query(db.User).count() == 1
def test_trying_to_delete_someone_else_without_privileges(test_ctx): def test_trying_to_delete_someone_else_without_privileges(test_ctx):
user1 = test_ctx.user_factory(name='u1', rank='regular_user') user1 = test_ctx.user_factory(name='u1', rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(name='u2', rank='regular_user') user2 = test_ctx.user_factory(name='u2', rank=db.User.RANK_REGULAR)
db.session.add_all([user1, user2]) db.session.add_all([user1, user2])
db.session.commit() db.session.commit()
with pytest.raises(errors.AuthError): with pytest.raises(errors.AuthError):
@ -47,4 +46,4 @@ def test_trying_to_delete_non_existing(test_ctx):
with pytest.raises(users.UserNotFoundError): with pytest.raises(users.UserNotFoundError):
test_ctx.api.delete( test_ctx.api.delete(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), 'bad') user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)), 'bad')

View file

@ -6,12 +6,10 @@ from szurubooru.func import util, users
@pytest.fixture @pytest.fixture
def test_ctx(context_factory, config_injector, user_factory): def test_ctx(context_factory, config_injector, user_factory):
config_injector({ config_injector({
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {'regular_user': 'Peasant'},
'privileges': { 'privileges': {
'users:list': 'regular_user', 'users:list': db.User.RANK_REGULAR,
'users:view': 'regular_user', 'users:view': db.User.RANK_REGULAR,
'users:edit:any:email': 'mod', 'users:edit:any:email': db.User.RANK_MODERATOR,
}, },
'thumbnails': {'avatar_width': 200}, 'thumbnails': {'avatar_width': 200},
}) })
@ -23,13 +21,13 @@ def test_ctx(context_factory, config_injector, user_factory):
return ret return ret
def test_retrieving_multiple(test_ctx): def test_retrieving_multiple(test_ctx):
user1 = test_ctx.user_factory(name='u1', rank='mod') user1 = test_ctx.user_factory(name='u1', rank=db.User.RANK_MODERATOR)
user2 = test_ctx.user_factory(name='u2', rank='mod') user2 = test_ctx.user_factory(name='u2', rank=db.User.RANK_MODERATOR)
db.session.add_all([user1, user2]) db.session.add_all([user1, user2])
result = test_ctx.list_api.get( result = test_ctx.list_api.get(
test_ctx.context_factory( test_ctx.context_factory(
input={'query': '', 'page': 1}, input={'query': '', 'page': 1},
user=test_ctx.user_factory(rank='regular_user'))) user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)))
assert result['query'] == '' assert result['query'] == ''
assert result['page'] == 1 assert result['page'] == 1
assert result['pageSize'] == 100 assert result['pageSize'] == 100
@ -44,16 +42,15 @@ def test_trying_to_retrieve_multiple_without_privileges(test_ctx):
user=test_ctx.user_factory(rank='anonymous'))) user=test_ctx.user_factory(rank='anonymous')))
def test_retrieving_single(test_ctx): def test_retrieving_single(test_ctx):
db.session.add(test_ctx.user_factory(name='u1', rank='regular_user')) db.session.add(test_ctx.user_factory(name='u1', rank=db.User.RANK_REGULAR))
result = test_ctx.detail_api.get( result = test_ctx.detail_api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'u1') 'u1')
assert result == { assert result == {
'user': { 'user': {
'name': 'u1', 'name': 'u1',
'rank': 'regular_user', 'rank': db.User.RANK_REGULAR,
'rankName': 'Peasant',
'creationTime': datetime.datetime(1997, 1, 1), 'creationTime': datetime.datetime(1997, 1, 1),
'lastLoginTime': None, 'lastLoginTime': None,
'avatarStyle': 'gravatar', 'avatarStyle': 'gravatar',
@ -66,7 +63,7 @@ def test_trying_to_retrieve_single_non_existing(test_ctx):
with pytest.raises(users.UserNotFoundError): with pytest.raises(users.UserNotFoundError):
test_ctx.detail_api.get( test_ctx.detail_api.get(
test_ctx.context_factory( test_ctx.context_factory(
user=test_ctx.user_factory(rank='regular_user')), user=test_ctx.user_factory(rank=db.User.RANK_REGULAR)),
'-') '-')
def test_trying_to_retrieve_single_without_privileges(test_ctx): def test_trying_to_retrieve_single_without_privileges(test_ctx):

View file

@ -15,19 +15,17 @@ def test_ctx(config_injector, context_factory, user_factory):
'user_name_regex': '^[^!]{3,}$', 'user_name_regex': '^[^!]{3,}$',
'password_regex': '^[^!]{3,}$', 'password_regex': '^[^!]{3,}$',
'thumbnails': {'avatar_width': 200, 'avatar_height': 200}, 'thumbnails': {'avatar_width': 200, 'avatar_height': 200},
'ranks': ['anonymous', 'regular_user', 'mod', 'admin'],
'rank_names': {},
'privileges': { 'privileges': {
'users:edit:self:name': 'regular_user', 'users:edit:self:name': db.User.RANK_REGULAR,
'users:edit:self:pass': 'regular_user', 'users:edit:self:pass': db.User.RANK_REGULAR,
'users:edit:self:email': 'regular_user', 'users:edit:self:email': db.User.RANK_REGULAR,
'users:edit:self:rank': 'mod', 'users:edit:self:rank': db.User.RANK_MODERATOR,
'users:edit:self:avatar': 'mod', 'users:edit:self:avatar': db.User.RANK_MODERATOR,
'users:edit:any:name': 'mod', 'users:edit:any:name': db.User.RANK_MODERATOR,
'users:edit:any:pass': 'mod', 'users:edit:any:pass': db.User.RANK_MODERATOR,
'users:edit:any:email': 'mod', 'users:edit:any:email': db.User.RANK_MODERATOR,
'users:edit:any:rank': 'admin', 'users:edit:any:rank': db.User.RANK_ADMINISTRATOR,
'users:edit:any:avatar': 'admin', 'users:edit:any:avatar': db.User.RANK_ADMINISTRATOR,
}, },
}) })
ret = util.dotdict() ret = util.dotdict()
@ -37,7 +35,7 @@ def test_ctx(config_injector, context_factory, user_factory):
return ret return ret
def test_updating_user(test_ctx): def test_updating_user(test_ctx):
user = test_ctx.user_factory(name='u1', rank='admin') user = test_ctx.user_factory(name='u1', rank=db.User.RANK_ADMINISTRATOR)
db.session.add(user) db.session.add(user)
result = test_ctx.api.put( result = test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(
@ -45,7 +43,7 @@ def test_updating_user(test_ctx):
'name': 'chewie', 'name': 'chewie',
'email': 'asd@asd.asd', 'email': 'asd@asd.asd',
'password': 'oks', 'password': 'oks',
'rank': 'mod', 'rank': 'moderator',
'avatarStyle': 'gravatar', 'avatarStyle': 'gravatar',
}, },
user=user), user=user),
@ -59,14 +57,13 @@ def test_updating_user(test_ctx):
'lastLoginTime': None, 'lastLoginTime': None,
'email': 'asd@asd.asd', 'email': 'asd@asd.asd',
'name': 'chewie', 'name': 'chewie',
'rank': 'mod', 'rank': 'moderator',
'rankName': 'Unknown',
} }
} }
user = users.get_user_by_name('chewie') user = users.get_user_by_name('chewie')
assert user.name == 'chewie' assert user.name == 'chewie'
assert user.email == 'asd@asd.asd' assert user.email == 'asd@asd.asd'
assert user.rank == 'mod' assert user.rank == db.User.RANK_MODERATOR
assert user.avatar_style == user.AVATAR_GRAVATAR assert user.avatar_style == user.AVATAR_GRAVATAR
assert auth.is_valid_password(user, 'oks') is True assert auth.is_valid_password(user, 'oks') is True
assert auth.is_valid_password(user, 'invalid') is False assert auth.is_valid_password(user, 'invalid') is False
@ -90,7 +87,7 @@ def test_updating_user(test_ctx):
({'avatarStyle': 'manual'}, users.InvalidAvatarError), # missing file ({'avatarStyle': 'manual'}, users.InvalidAvatarError), # missing file
]) ])
def test_trying_to_pass_invalid_input(test_ctx, input, expected_exception): def test_trying_to_pass_invalid_input(test_ctx, input, expected_exception):
user = test_ctx.user_factory(name='u1', rank='admin') user = test_ctx.user_factory(name='u1', rank='administrator')
db.session.add(user) db.session.add(user)
with pytest.raises(expected_exception): with pytest.raises(expected_exception):
test_ctx.api.put( test_ctx.api.put(
@ -101,13 +98,13 @@ def test_trying_to_pass_invalid_input(test_ctx, input, expected_exception):
def test_omitting_optional_field(test_ctx, tmpdir, field): def test_omitting_optional_field(test_ctx, tmpdir, field):
config.config['data_dir'] = str(tmpdir.mkdir('data')) config.config['data_dir'] = str(tmpdir.mkdir('data'))
config.config['data_url'] = 'http://example.com/data/' config.config['data_url'] = 'http://example.com/data/'
user = test_ctx.user_factory(name='u1', rank='admin') user = test_ctx.user_factory(name='u1', rank='administrator')
db.session.add(user) db.session.add(user)
input = { input = {
'name': 'chewie', 'name': 'chewie',
'email': 'asd@asd.asd', 'email': 'asd@asd.asd',
'password': 'oks', 'password': 'oks',
'rank': 'mod', 'rank': 'moderator',
'avatarStyle': 'gravatar', 'avatarStyle': 'gravatar',
} }
del input[field] del input[field]
@ -120,13 +117,13 @@ def test_omitting_optional_field(test_ctx, tmpdir, field):
assert result is not None assert result is not None
def test_trying_to_update_non_existing(test_ctx): def test_trying_to_update_non_existing(test_ctx):
user = test_ctx.user_factory(name='u1', rank='admin') user = test_ctx.user_factory(name='u1', rank='administrator')
db.session.add(user) db.session.add(user)
with pytest.raises(users.UserNotFoundError): with pytest.raises(users.UserNotFoundError):
test_ctx.api.put(test_ctx.context_factory(user=user), 'u2') test_ctx.api.put(test_ctx.context_factory(user=user), 'u2')
def test_removing_email(test_ctx): def test_removing_email(test_ctx):
user = test_ctx.user_factory(name='u1', rank='admin') user = test_ctx.user_factory(name='u1', rank='administrator')
db.session.add(user) db.session.add(user)
test_ctx.api.put( test_ctx.api.put(
test_ctx.context_factory(input={'email': ''}, user=user), 'u1') test_ctx.context_factory(input={'email': ''}, user=user), 'u1')
@ -140,16 +137,16 @@ def test_removing_email(test_ctx):
{'avatarStyle': 'whatever'}, {'avatarStyle': 'whatever'},
]) ])
def test_trying_to_update_someone_else(test_ctx, input): def test_trying_to_update_someone_else(test_ctx, input):
user1 = test_ctx.user_factory(name='u1', rank='regular_user') user1 = test_ctx.user_factory(name='u1', rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(name='u2', rank='regular_user') user2 = test_ctx.user_factory(name='u2', rank=db.User.RANK_REGULAR)
db.session.add_all([user1, user2]) db.session.add_all([user1, user2])
with pytest.raises(errors.AuthError): with pytest.raises(errors.AuthError):
test_ctx.api.put( test_ctx.api.put(
test_ctx.context_factory(input=input, user=user1), user2.name) test_ctx.context_factory(input=input, user=user1), user2.name)
def test_trying_to_become_someone_else(test_ctx): def test_trying_to_become_someone_else(test_ctx):
user1 = test_ctx.user_factory(name='me', rank='regular_user') user1 = test_ctx.user_factory(name='me', rank=db.User.RANK_REGULAR)
user2 = test_ctx.user_factory(name='her', rank='regular_user') user2 = test_ctx.user_factory(name='her', rank=db.User.RANK_REGULAR)
db.session.add_all([user1, user2]) db.session.add_all([user1, user2])
with pytest.raises(users.UserAlreadyExistsError): with pytest.raises(users.UserAlreadyExistsError):
test_ctx.api.put( test_ctx.api.put(
@ -160,10 +157,10 @@ def test_trying_to_become_someone_else(test_ctx):
test_ctx.context_factory(input={'name': 'HER'}, user=user1), 'me') test_ctx.context_factory(input={'name': 'HER'}, user=user1), 'me')
def test_mods_trying_to_become_admin(test_ctx): def test_mods_trying_to_become_admin(test_ctx):
user1 = test_ctx.user_factory(name='u1', rank='mod') user1 = test_ctx.user_factory(name='u1', rank=db.User.RANK_MODERATOR)
user2 = test_ctx.user_factory(name='u2', rank='mod') user2 = test_ctx.user_factory(name='u2', rank=db.User.RANK_MODERATOR)
db.session.add_all([user1, user2]) db.session.add_all([user1, user2])
context = test_ctx.context_factory(input={'rank': 'admin'}, user=user1) context = test_ctx.context_factory(input={'rank': 'administrator'}, user=user1)
with pytest.raises(errors.AuthError): with pytest.raises(errors.AuthError):
test_ctx.api.put(context, user1.name) test_ctx.api.put(context, user1.name)
with pytest.raises(errors.AuthError): with pytest.raises(errors.AuthError):
@ -172,7 +169,7 @@ def test_mods_trying_to_become_admin(test_ctx):
def test_uploading_avatar(test_ctx, tmpdir): def test_uploading_avatar(test_ctx, tmpdir):
config.config['data_dir'] = str(tmpdir.mkdir('data')) config.config['data_dir'] = str(tmpdir.mkdir('data'))
config.config['data_url'] = 'http://example.com/data/' config.config['data_url'] = 'http://example.com/data/'
user = test_ctx.user_factory(name='u1', rank='mod') user = test_ctx.user_factory(name='u1', rank=db.User.RANK_MODERATOR)
db.session.add(user) db.session.add(user)
response = test_ctx.api.put( response = test_ctx.api.put(
test_ctx.context_factory( test_ctx.context_factory(

View file

@ -90,7 +90,7 @@ def config_injector():
@pytest.fixture @pytest.fixture
def user_factory(): def user_factory():
def factory(name=None, rank='regular_user', email='dummy'): def factory(name=None, rank=db.User.RANK_REGULAR, email='dummy'):
user = db.User() user = db.User()
user.name = name or get_unique_name() user.name = name or get_unique_name()
user.password_salt = 'dummy' user.password_salt = 'dummy'