diff --git a/app/blueprints/packages/packages.py b/app/blueprints/packages/packages.py
index 4399267d..5d8711af 100644
--- a/app/blueprints/packages/packages.py
+++ b/app/blueprints/packages/packages.py
@@ -176,7 +176,7 @@ def view(package):
threads = Thread.query.filter_by(package_id=package.id, review_id=None)
if not current_user.is_authenticated:
threads = threads.filter_by(private=False)
- elif not current_user.rank.atLeast(UserRank.EDITOR) and not current_user == package.author:
+ elif not current_user.rank.atLeast(UserRank.APPROVER) and not current_user == package.author:
threads = threads.filter(or_(Thread.private == False, Thread.author == current_user))
has_review = current_user.is_authenticated and PackageReview.query.filter_by(package=package, author=current_user).count() > 0
@@ -519,7 +519,8 @@ def remove_self_maintainers(package):
@login_required
@is_package_page
def audit(package):
- if not package.checkPerm(current_user, Permission.EDIT_PACKAGE):
+ if not (package.checkPerm(current_user, Permission.EDIT_PACKAGE) or
+ package.checkPerm(current_user, Permission.APPROVE_NEW)):
abort(403)
page = get_int_or_abort(request.args.get("page"), 1)
diff --git a/app/blueprints/threads/__init__.py b/app/blueprints/threads/__init__.py
index 7a6493fe..710d4355 100644
--- a/app/blueprints/threads/__init__.py
+++ b/app/blueprints/threads/__init__.py
@@ -240,8 +240,8 @@ def view(id):
addNotification(thread.watchers, current_user, NotificationType.THREAD_REPLY, msg, thread.getViewURL(), thread.package)
if thread.author == get_system_user():
- editors = User.query.filter(User.rank >= UserRank.EDITOR).all()
- addNotification(editors, current_user, NotificationType.EDITOR_MISC, msg,
+ approvers = User.query.filter(User.rank >= UserRank.APPROVER).all()
+ addNotification(approvers, current_user, NotificationType.EDITOR_MISC, msg,
thread.getViewURL(), thread.package)
db.session.commit()
@@ -336,8 +336,8 @@ def new():
if package is not None:
addNotification(package.maintainers, current_user, NotificationType.NEW_THREAD, notif_msg, thread.getViewURL(), package)
- editors = User.query.filter(User.rank >= UserRank.EDITOR).all()
- addNotification(editors, current_user, NotificationType.EDITOR_MISC, notif_msg, thread.getViewURL(), package)
+ approvers = User.query.filter(User.rank >= UserRank.APPROVER).all()
+ addNotification(approvers, current_user, NotificationType.EDITOR_MISC, notif_msg, thread.getViewURL(), package)
db.session.commit()
diff --git a/app/blueprints/todo/__init__.py b/app/blueprints/todo/__init__.py
index 5bb30b92..be9aa80c 100644
--- a/app/blueprints/todo/__init__.py
+++ b/app/blueprints/todo/__init__.py
@@ -99,7 +99,7 @@ def topics():
page = get_int_or_abort(request.args.get("page"), 1)
num = get_int_or_abort(request.args.get("n"), 100)
- if num > 100 and not current_user.rank.atLeast(UserRank.EDITOR):
+ if num > 100 and not current_user.rank.atLeast(UserRank.APPROVER):
num = 100
query = query.paginate(page, num, True)
@@ -160,7 +160,7 @@ def view_user(username=None):
if not user:
abort(404)
- if current_user != user and not current_user.rank.atLeast(UserRank.EDITOR):
+ if current_user != user and not current_user.rank.atLeast(UserRank.APPROVER):
abort(403)
unapproved_packages = user.packages \
diff --git a/app/flatpages/help/ranks_permissions.md b/app/flatpages/help/ranks_permissions.md
index 31568ef4..143214ae 100644
--- a/app/flatpages/help/ranks_permissions.md
+++ b/app/flatpages/help/ranks_permissions.md
@@ -5,7 +5,8 @@ title: Ranks and Permissions
* **New Members** - mostly untrusted, cannot change package meta data or publish releases without approval.
* **Members** - Trusted to change the meta data of their own packages', but cannot approve their own packages.
* **Trusted Members** - Same as above, but can approve their own releases.
-* **Editors** - Trusted to edit any package or release, and also responsible for approving new packages.
+* **Approvers** - Responsible for approving new packages, screenshots, and releases.
+* **Editors** - Same as above, and can edit any package or release.
* **Moderators** - Same as above, but can manage users.
* **Admins** - Full access.
@@ -18,6 +19,7 @@ title: Ranks and Permissions
New Member
Member
Trusted
+
Approver
Editor
Moderator
Admin
@@ -36,6 +38,8 @@ title: Ranks and Permissions
N
Y
N
+
Y
+
N
@@ -47,6 +51,8 @@ title: Ranks and Permissions
✓
+
✓
+
✓
✓
✓
@@ -62,6 +68,8 @@ title: Ranks and Permissions
+
✓
+
✓
✓
✓
✓
@@ -77,6 +85,8 @@ title: Ranks and Permissions
✓
+
✓
+
✓
✓
✓
✓
@@ -92,6 +102,8 @@ title: Ranks and Permissions
✓
+
✓
+
✓
✓
✓
@@ -107,8 +119,10 @@ title: Ranks and Permissions
✓
-
✓
+
✓
+
✓
+
✓
✓
✓
✓
@@ -122,6 +136,8 @@ title: Ranks and Permissions
✓
+
✓
+
✓
✓
✓
@@ -137,6 +153,8 @@ title: Ranks and Permissions
✓
+
✓
+
✓
✓
✓
✓
@@ -152,6 +170,8 @@ title: Ranks and Permissions
✓
+
✓
+
✓
✓
✓
@@ -167,6 +187,8 @@ title: Ranks and Permissions
✓
+
✓
+
✓
✓
✓
✓
@@ -182,6 +204,8 @@ title: Ranks and Permissions
+
+
@@ -197,6 +221,8 @@ title: Ranks and Permissions
✓
+
✓
+
✓
✓
✓
✓
@@ -212,6 +238,8 @@ title: Ranks and Permissions
✓
+
✓
+
✓
✓
@@ -227,6 +255,8 @@ title: Ranks and Permissions
✓
+
✓
+
✓
✓
@@ -242,6 +272,8 @@ title: Ranks and Permissions
✓
+
✓
+
✓
✓
@@ -257,10 +289,12 @@ title: Ranks and Permissions
+
+
-
✓3
-
✓23
+
✓2
+
✓12
✓
✓
@@ -268,5 +302,5 @@ title: Ranks and Permissions
-2. Target user cannot be an admin.
-3. Cannot set user to a higher rank than themselves.
+1. Target user cannot be an admin.
+2 Cannot set user to a higher rank than themselves.
diff --git a/app/models/packages.py b/app/models/packages.py
index 24a51139..a9b9e77d 100644
--- a/app/models/packages.py
+++ b/app/models/packages.py
@@ -520,6 +520,7 @@ class Package(db.Model):
isOwner = user == self.author
isMaintainer = isOwner or user.rank.atLeast(UserRank.EDITOR) or user in self.maintainers
+ isApprover = user.rank.atLeast(UserRank.APPROVER)
if perm == Permission.CREATE_THREAD:
return user.rank.atLeast(UserRank.MEMBER)
@@ -528,25 +529,30 @@ class Package(db.Model):
elif perm == Permission.MAKE_RELEASE or perm == Permission.ADD_SCREENSHOTS:
return isMaintainer
- elif perm == Permission.EDIT_PACKAGE or \
- perm == Permission.APPROVE_CHANGES or perm == Permission.APPROVE_RELEASE:
+ elif perm == Permission.EDIT_PACKAGE:
return isMaintainer and user.rank.atLeast(UserRank.MEMBER if self.approved else UserRank.NEW_MEMBER)
+ elif perm == Permission.APPROVE_RELEASE:
+ return (isMaintainer or isApprover) and user.rank.atLeast(UserRank.MEMBER if self.approved else UserRank.NEW_MEMBER)
+
# Anyone can change the package name when not approved, but only editors when approved
elif perm == Permission.CHANGE_NAME:
return not self.approved or user.rank.atLeast(UserRank.EDITOR)
# Editors can change authors and approve new packages
elif perm == Permission.APPROVE_NEW or perm == Permission.CHANGE_AUTHOR:
- return user.rank.atLeast(UserRank.EDITOR)
+ return isApprover
elif perm == Permission.APPROVE_SCREENSHOT:
- return isMaintainer and user.rank.atLeast(UserRank.TRUSTED_MEMBER if self.approved else UserRank.NEW_MEMBER)
+ return (isMaintainer or isApprover) and \
+ user.rank.atLeast(UserRank.TRUSTED_MEMBER if self.approved else UserRank.NEW_MEMBER)
- elif perm == Permission.EDIT_MAINTAINERS or perm == Permission.UNAPPROVE_PACKAGE or \
- perm == Permission.DELETE_PACKAGE:
+ elif perm == Permission.EDIT_MAINTAINERS or perm == Permission.DELETE_PACKAGE:
return isOwner or user.rank.atLeast(UserRank.EDITOR)
+ elif perm == Permission.UNAPPROVE_PACKAGE:
+ return isOwner or user.rank.atLeast(UserRank.APPROVER)
+
elif perm == Permission.CHANGE_RELEASE_URL:
return user.rank.atLeast(UserRank.MODERATOR)
@@ -575,9 +581,10 @@ class Package(db.Model):
return False
if state == PackageState.READY_FOR_REVIEW or state == PackageState.APPROVED:
- requiredPerm = Permission.APPROVE_NEW if state == PackageState.APPROVED else Permission.EDIT_PACKAGE
+ if state == PackageState.APPROVED and not self.checkPerm(user, Permission.APPROVE_NEW):
+ return False
- if not self.checkPerm(user, requiredPerm):
+ if not (self.checkPerm(user, Permission.APPROVE_NEW) or self.checkPerm(user, Permission.EDIT_PACKAGE)):
return False
if state == PackageState.APPROVED and ("Other" in self.license.name or "Other" in self.media_license.name):
@@ -881,7 +888,7 @@ class PackageRelease(db.Model):
return count > 0
elif perm == Permission.APPROVE_RELEASE:
- return user.rank.atLeast(UserRank.EDITOR) or \
+ return user.rank.atLeast(UserRank.APPROVER) or \
(isMaintainer and user.rank.atLeast(
UserRank.MEMBER if self.approved else UserRank.NEW_MEMBER))
else:
diff --git a/app/models/threads.py b/app/models/threads.py
index 2be48f17..f002942e 100644
--- a/app/models/threads.py
+++ b/app/models/threads.py
@@ -76,7 +76,7 @@ class Thread(db.Model):
if self.package:
isMaintainer = isMaintainer or user in self.package.maintainers
- canSee = not self.private or isMaintainer or user.rank.atLeast(UserRank.EDITOR)
+ canSee = not self.private or isMaintainer or user.rank.atLeast(UserRank.APPROVER)
if perm == Permission.SEE_THREAD:
return canSee
diff --git a/app/models/users.py b/app/models/users.py
index b12b7911..81792d4a 100644
--- a/app/models/users.py
+++ b/app/models/users.py
@@ -31,10 +31,11 @@ class UserRank(enum.Enum):
NEW_MEMBER = 2
MEMBER = 3
TRUSTED_MEMBER = 4
- EDITOR = 5
- BOT = 6
- MODERATOR = 7
- ADMIN = 8
+ APPROVER = 5
+ EDITOR = 6
+ BOT = 7
+ MODERATOR = 8
+ ADMIN = 9
def atLeast(self, min):
return self.value >= min.value
@@ -59,7 +60,6 @@ class UserRank(enum.Enum):
class Permission(enum.Enum):
EDIT_PACKAGE = "EDIT_PACKAGE"
- APPROVE_CHANGES = "APPROVE_CHANGES"
DELETE_PACKAGE = "DELETE_PACKAGE"
CHANGE_AUTHOR = "CHANGE_AUTHOR"
CHANGE_NAME = "CHANGE_NAME"
@@ -96,13 +96,14 @@ class Permission(enum.Enum):
return False
if self == Permission.APPROVE_NEW or \
- self == Permission.APPROVE_CHANGES or \
self == Permission.APPROVE_RELEASE or \
self == Permission.APPROVE_SCREENSHOT or \
- self == Permission.EDIT_TAGS or \
- self == Permission.CREATE_TAG or \
self == Permission.SEE_THREAD:
+ return user.rank.atLeast(UserRank.APPROVER)
+
+ elif self == Permission.EDIT_TAGS or self == Permission.CREATE_TAG:
return user.rank.atLeast(UserRank.EDITOR)
+
else:
raise Exception("Non-global permission checked globally. Use Package.checkPerm or User.checkPerm instead.")
@@ -186,8 +187,7 @@ class User(db.Model, UserMixin):
def canAccessTodoList(self):
return Permission.APPROVE_NEW.check(self) or \
- Permission.APPROVE_RELEASE.check(self) or \
- Permission.APPROVE_CHANGES.check(self)
+ Permission.APPROVE_RELEASE.check(self)
def isClaimed(self):
return self.rank.atLeast(UserRank.NEW_MEMBER)
diff --git a/app/scss/components.scss b/app/scss/components.scss
index 554e009c..76ddb77f 100644
--- a/app/scss/components.scss
+++ b/app/scss/components.scss
@@ -70,7 +70,7 @@
}
.NOT_JOINED a, .NOT_JOINED {
- color: #7ac !important;
+ color: #aaa !important;
}
.ADMIN a, .ADMIN{
@@ -81,6 +81,10 @@
color: #e90 !important;
}
+.APPROVER a, .APPROVER {
+ color: #69f !important;
+}
+
.EDITOR a, .EDITOR {
color: #b6f !important;
}
diff --git a/app/templates/base.html b/app/templates/base.html
index 44d547b7..8a9d2148 100644
--- a/app/templates/base.html
+++ b/app/templates/base.html
@@ -6,7 +6,7 @@
{% block title %}title{% endblock %} - {{ config.USER_APP_NAME }}
-
+
diff --git a/app/templates/notifications/list.html b/app/templates/notifications/list.html
index 13858def..455d780a 100644
--- a/app/templates/notifications/list.html
+++ b/app/templates/notifications/list.html
@@ -63,7 +63,7 @@ Notifications
{% if editor_notifications %}
-
Editor Notifications
+
Editor/Approver Notifications
{% for n in editor_notifications %}
diff --git a/app/templates/packages/view.html b/app/templates/packages/view.html
index ea017428..422facf2 100644
--- a/app/templates/packages/view.html
+++ b/app/templates/packages/view.html
@@ -200,7 +200,7 @@
{% if review_thread.private %}
This thread is only visible to the package owner and users of
- Editor rank or above.
+ Approver rank or above.
{% endif %}
@@ -450,7 +450,7 @@
Report a problem with this listing
{% endif %}
- {% if package.checkPerm(current_user, "EDIT_PACKAGE") %}
+ {% if package.checkPerm(current_user, "EDIT_PACKAGE") or package.checkPerm(current_user, "APPROVE_NEW") %}
See audit log
diff --git a/app/templates/threads/new.html b/app/templates/threads/new.html
index c0fe5626..2516f9d0 100644
--- a/app/templates/threads/new.html
+++ b/app/templates/threads/new.html
@@ -37,7 +37,7 @@
{{ render_checkbox_field(form.private, class_="my-3") }}
- Only you, the package author, and users of Editor rank
+ Only you, the package author, and users of Approver rank
and above can read private threads.
diff --git a/app/templates/threads/view.html b/app/templates/threads/view.html
index 226a0dd5..23c32327 100644
--- a/app/templates/threads/view.html
+++ b/app/templates/threads/view.html
@@ -63,7 +63,7 @@
{% if thread.private %}
This thread is only visible to its creator, the package owner, and users of
- Editor rank or above.
+ Approver rank or above.
{% endif %}
diff --git a/app/templates/todo/todo_base.html b/app/templates/todo/todo_base.html
index 4f144460..e29e283e 100644
--- a/app/templates/todo/todo_base.html
+++ b/app/templates/todo/todo_base.html
@@ -1,7 +1,7 @@
{% extends "base.html" %}
{% block container %}
- {% if current_user.rank.atLeast(current_user.rank.EDITOR) %}
+ {% if current_user.rank.atLeast(current_user.rank.APPROVER) %}