Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Kontr 2.0
Portal API Backend
Commits
964d92ba
Unverified
Commit
964d92ba
authored
Sep 16, 2018
by
Peter Stanko
Browse files
New permissions for creating new submissions by other user
parent
ef048f2e
Changes
24
Hide whitespace changes
Inline
Side-by-side
management/data/shared.py
View file @
964d92ba
...
...
@@ -35,6 +35,8 @@ PERM_TEACHER = dict(
write_groups
=
True
,
write_projects
=
True
,
archive_projects
=
True
,
create_submissions_other
=
True
,
create_submissions
=
True
,
resubmit_submissions
=
True
,
evaluate_submissions
=
True
,
write_reviews_all
=
True
...
...
portal/database/models.py
View file @
964d92ba
...
...
@@ -71,9 +71,9 @@ class Client(db.Model):
id: UUID string
name: custom name for the secret
type: client type (worker or user)
secrets: a list of secrets for this client
roles: roles associated with this client
owner_id: reference to the enclosing entity of the client
-
secrets: a list of secrets for this client
-
roles: roles associated with this client
-
owner_id: reference to the enclosing entity of the client
"""
__tablename__
=
'client'
id
=
db
.
Column
(
db
.
String
(
length
=
36
),
default
=
lambda
:
str
(
...
...
@@ -744,6 +744,7 @@ class RolePermissions(db.Model, EntityBase):
archive_projects
=
db
.
Column
(
db
.
Boolean
,
default
=
False
,
nullable
=
False
)
create_submissions
=
db
.
Column
(
db
.
Boolean
,
default
=
False
,
nullable
=
False
)
create_submissions_other
=
db
.
Column
(
db
.
Boolean
,
default
=
False
,
nullable
=
False
)
resubmit_submissions
=
db
.
Column
(
db
.
Boolean
,
default
=
False
,
nullable
=
False
)
evaluate_submissions
=
db
.
Column
(
db
.
Boolean
,
default
=
False
,
nullable
=
False
)
...
...
portal/rest/courses.py
View file @
964d92ba
...
...
@@ -53,10 +53,10 @@ class CourseResource(Resource):
course
=
find_course
(
cid
)
# authorization
perm_service
=
permissions
.
PermissionsService
(
course
=
course
)
if
perm_service
.
check
.
client
([
'view_course_full'
]):
if
perm_service
.
check
.
permissions
([
'view_course_full'
]):
return
course_schema
.
dump
(
course
)
elif
perm_service
.
check
.
client
([
'view_course_limited'
]):
elif
perm_service
.
check
.
permissions
([
'view_course_limited'
]):
dump
=
course_schema
.
dump
(
course
)
filtered_course
=
filter_course_dump
(
course
,
dump
.
data
,
client
)
return
filtered_course
...
...
@@ -78,7 +78,7 @@ class CourseResource(Resource):
def
put
(
self
,
cid
:
str
):
course
=
find_course
(
cid
)
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
client
([
'
update_course
'
]
)
permissions
.
PermissionsService
(
course
=
course
).
require
.
update_course
(
)
data
=
rest_helpers
.
parse_request_data
(
schema
=
course_schema
,
action
=
'update'
,
resource
=
'course'
,
partial
=
True
...
...
@@ -98,7 +98,7 @@ class CourseNotesToken(Resource):
def
get
(
self
,
cid
):
course
=
find_course
(
cid
)
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
c
lient
([
'handle_notes
_access_token
'
]
)
permissions
.
PermissionsService
(
course
=
course
).
require
.
c
ourse
_access_token
(
)
return
course
.
notes_access_token
@
jwt_required
...
...
@@ -108,7 +108,7 @@ class CourseNotesToken(Resource):
def
put
(
self
,
cid
):
course
=
find_course
(
cid
)
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
c
lient
([
'handle_notes
_access_token
'
]
)
permissions
.
PermissionsService
(
course
=
course
).
require
.
c
ourse
_access_token
(
)
json_data
=
rest_helpers
.
require_data
(
action
=
'update_notes_token'
,
resource
=
'course'
)
...
...
@@ -128,7 +128,7 @@ class CourseImport(Resource):
def
put
(
self
,
cid
:
str
):
course
=
find_course
(
cid
)
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
client
([
'
update_course
'
]
)
permissions
.
PermissionsService
(
course
=
course
).
require
.
update_course
(
)
data
=
rest_helpers
.
parse_request_data
(
course_import_schema
,
action
=
'import'
,
resource
=
'course'
...
...
@@ -154,7 +154,7 @@ class CourseUsers(Resource):
@
courses_namespace
.
response
(
403
,
'Not allowed to see users in the course'
)
def
get
(
self
,
cid
):
course
=
find_course
(
cid
)
permissions
.
PermissionsService
(
course
=
course
).
require
.
client
([
'view_course_full'
])
permissions
.
PermissionsService
(
course
=
course
).
require
.
permissions
([
'view_course_full'
])
group_ids
=
request
.
args
.
getlist
(
'group'
)
role_ids
=
request
.
args
.
getlist
(
'role'
)
users
=
CourseService
(
course
=
course
).
get_users_filtered
(
group_ids
,
role_ids
)
...
...
portal/rest/groups.py
View file @
964d92ba
...
...
@@ -33,9 +33,7 @@ class GroupsList(Resource):
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
update_course
()
data
=
rest_helpers
.
parse_request_data
(
group_schema
,
action
=
'create'
,
resource
=
'group'
)
data
=
rest_helpers
.
parse_request_data
(
group_schema
,
action
=
'create'
,
resource
=
'group'
)
new_group
=
GroupService
().
create_group
(
course
,
**
data
)
return
group_schema
.
dump
(
new_group
)[
0
],
201
...
...
portal/rest/login.py
View file @
964d92ba
...
...
@@ -5,7 +5,7 @@ from flask_restplus import Namespace, Resource, fields
from
portal
import
logger
from
portal.database.models
import
Client
from
portal.service.auth
import
login_gitlab
,
login_username_password
,
login_secret
from
portal.service.auth
import
login_gitlab
,
login_secret
,
login_username_password
from
portal.service.errors
import
PortalAPIError
,
UnauthorizedError
log
=
logger
.
get_logger
(
__name__
)
...
...
@@ -50,8 +50,8 @@ class Refresh(Resource):
@
auth_namespace
.
marshal_with
(
refresh_schema
)
@
auth_namespace
.
response
(
401
,
'Client is not authorized'
)
def
post
(
self
):
client
=
authorized_client
()
return
dict
(
access_token
=
create_access_token
(
identity
=
client
))
client
_id
=
authorized_client
()
return
dict
(
access_token
=
create_access_token
(
identity
=
client
_id
))
@
auth_namespace
.
route
(
'/logout'
)
...
...
@@ -60,11 +60,11 @@ class Logout(Resource):
@
auth_namespace
.
marshal_with
(
logout_schema
)
@
auth_namespace
.
response
(
401
,
'Client is not authorized'
)
def
post
(
self
):
authorized_client
()
return
dict
(
access_token
=
None
,
refresh_token
=
None
)
client_id
=
authorized_client
()
return
dict
(
id
=
client_id
,
access_token
=
None
,
refresh_token
=
None
)
def
authorized_client
():
def
authorized_client
()
->
str
:
client
=
get_jwt_identity
()
if
not
client
:
raise
UnauthorizedError
()
...
...
portal/rest/projects.py
View file @
964d92ba
...
...
@@ -155,7 +155,7 @@ class ProjectSubmissions(Resource):
course
=
general
.
find_course
(
cid
)
# authorization
perm
=
[
'read_submissions_all'
]
permissions
.
PermissionsService
(
course
=
course
).
require
.
client
(
perm
)
permissions
.
PermissionsService
(
course
=
course
).
require
.
permissions
(
perm
)
user_id
=
request
.
args
.
get
(
'user'
)
project
=
general
.
find_project
(
course
,
pid
)
...
...
@@ -167,13 +167,14 @@ class ProjectSubmissions(Resource):
def
post
(
self
,
cid
:
str
,
pid
:
str
):
client
=
auth
.
find_client
()
course
=
general
.
find_course
(
cid
)
user
=
request
.
args
.
get
(
'user'
)
user
=
general
.
find_user
(
user
)
if
user
is
not
None
else
client
# authorization
perm
=
[
'create_submissions'
]
permissions
.
PermissionsService
(
course
=
course
).
require
.
client
(
perm
)
permissions
.
PermissionsService
(
course
=
course
).
require
.
create_submission
(
user
)
# check if a new submission can be created by this user in this project
project
=
general
.
find_project
(
course
,
pid
)
_check_submission_create
(
client
,
project
)
_check_submission_create
(
user
,
project
)
data
=
rest_helpers
.
parse_request_data
(
submission_create_schema
,
action
=
'create'
,
resource
=
'submission'
...
...
@@ -183,7 +184,7 @@ class ProjectSubmissions(Resource):
# data for Kontr processing
service
=
SubmissionsService
()
new_submission
=
service
.
create_submission
(
user
=
client
,
user
=
user
,
project
=
project
,
submission_params
=
data
)
...
...
@@ -216,9 +217,9 @@ def _check_submission_create(client, project):
def
get_config_schema_based_on_permissions
(
course
):
perm_service
=
permissions
.
PermissionsService
(
course
=
course
)
if
perm_service
.
check
.
client
([
'view_course_full'
]):
if
perm_service
.
check
.
permissions
([
'view_course_full'
]):
return
config_schema
elif
perm_service
.
check
.
client
([
'view_course_limited'
]):
elif
perm_service
.
check
.
permissions
([
'view_course_limited'
]):
return
config_schema_reduced
else
:
raise
ForbiddenError
(
perm_service
.
client
)
portal/rest/roles.py
View file @
964d92ba
...
...
@@ -163,7 +163,7 @@ class RoleUsersList(Resource):
@
roles_namespace
.
response
(
404
,
'Client not found'
)
class
RoleClient
(
Resource
):
@
jwt_required
@
roles_namespace
.
response
(
204
,
'Adds
client
to role'
)
@
roles_namespace
.
response
(
204
,
'Adds
permissions
to role'
)
def
put
(
self
,
cid
:
str
,
rid
:
str
,
clid
:
str
):
course
=
general
.
find_course
(
cid
)
# authorization
...
...
@@ -175,7 +175,7 @@ class RoleClient(Resource):
return
''
,
204
@
jwt_required
@
roles_namespace
.
response
(
204
,
'Removes
client
from role'
)
@
roles_namespace
.
response
(
204
,
'Removes
permissions
from role'
)
def
delete
(
self
,
cid
:
str
,
rid
:
str
,
clid
:
str
):
course
=
general
.
find_course
(
cid
)
permissions
.
PermissionsService
(
course
=
course
).
require
.
write_roles
()
...
...
portal/rest/schemas.py
View file @
964d92ba
...
...
@@ -224,6 +224,7 @@ class RolePermissionsSchema(BaseSchema, Schema):
archive_projects
=
fields
.
Bool
()
create_submissions
=
fields
.
Bool
()
create_submissions_other
=
fields
.
Bool
()
resubmit_submissions
=
fields
.
Bool
()
evaluate_submissions
=
fields
.
Bool
()
...
...
@@ -293,7 +294,7 @@ class SecretSchema(BaseSchema, Schema):
"""
name
=
fields
.
Str
()
expires_at
=
fields
.
LocalDateTime
(
dump_only
=
True
)
client
=
NESTED
(
'
client
'
)
client
=
NESTED
(
'
permissions
'
)
class
CourseImportConfigSchema
(
Schema
):
...
...
portal/rest/submissions.py
View file @
964d92ba
...
...
@@ -167,7 +167,7 @@ class SubmissionResultFiles(Resource):
submission
=
general
.
find_submission
(
sid
)
# authorization
course
=
submission
.
project
.
course
permissions
.
PermissionsService
(
course
=
course
).
require
.
client
([
'evaluate_submissions'
])
permissions
.
PermissionsService
(
course
=
course
).
require
.
permissions
([
'evaluate_submissions'
])
# todo: authorize worker
service
=
SubmissionsService
(
submission
=
submission
)
task
=
service
.
upload_results_to_storage
()
...
...
@@ -185,7 +185,7 @@ class SubmissionResubmit(Resource):
# authorization
course
=
source_submission
.
project
.
course
perm_service
=
permissions
.
PermissionsService
(
course
=
course
)
perm_service
.
require
.
client
(
permissions
=
[
'resubmit_submissions'
])
perm_service
.
require
.
permissions
(
permissions
=
[
'resubmit_submissions'
])
data
=
rest_helpers
.
parse_request_data
(
submission_schema
,
action
=
'resubmit'
,
resource
=
'submission'
...
...
portal/rest/users.py
View file @
964d92ba
...
...
@@ -304,10 +304,10 @@ def get_submissions_based_on_permissions_for_course(client, course_id, project_i
perm_service
=
permissions
.
PermissionsService
(
course
=
course
)
checks
=
[
perm_service
.
check
.
sysadmin
(),
perm_service
.
check
.
client
([
'read_submissions_all'
]),
(
perm_service
.
check
.
client
([
'read_submissions_groups'
])
perm_service
.
check
.
permissions
([
'read_submissions_all'
]),
(
perm_service
.
check
.
permissions
([
'read_submissions_groups'
])
and
find_groups_intersection
(
client_owner
,
user
)),
(
perm_service
.
check
.
client
([
'read_submissions_own'
])
(
perm_service
.
check
.
permissions
([
'read_submissions_own'
])
and
client_owner
==
user
)
]
perm_service
.
require
.
any_check
(
client
,
*
checks
)
...
...
portal/service/auth.py
View file @
964d92ba
...
...
@@ -70,7 +70,7 @@ def login_secret(identifier: str, secret: str) -> Client:
def
validate_gitlab_token
(
token
:
str
,
username
:
str
,
throws
:
bool
=
True
):
"""Validates gitlab access token using the gitlab
client
"""Validates gitlab access token using the gitlab
permissions
Args:
token(str): Gitlab access token
username(str): Username
...
...
@@ -93,10 +93,10 @@ def find_client() -> Client:
def
__find_client_helper
(
identifier
:
str
)
->
Client
:
log
.
debug
(
f
"[LOGIN] Finding
client
using identifier:
{
identifier
}
"
)
log
.
debug
(
f
"[LOGIN] Finding
permissions
using identifier:
{
identifier
}
"
)
client
=
find_user
(
identifier
,
throws
=
False
)
if
not
client
:
client
=
find_worker
(
identifier
,
throws
=
False
)
if
not
client
:
raise
UnauthorizedError
(
f
"[LOGIN] Unknown
client
identifier
{
identifier
}
."
)
raise
UnauthorizedError
(
f
"[LOGIN] Unknown
permissions
identifier
{
identifier
}
."
)
return
client
portal/service/errors.py
View file @
964d92ba
...
...
@@ -108,7 +108,7 @@ class UnauthorizedError(PortalAPIError):
class
ForbiddenError
(
PortalAPIError
):
# could use a resource identification (like 404)
def
__init__
(
self
,
client
=
None
,
note
=
None
):
user_message
=
f
"Forbidden for
{
client
.
type
}
:
{
client
.
id
}
!"
if
client
else
\
user_message
=
f
"Forbidden for
{
permissions
.
type
}
:
{
permissions
.
id
}
!"
if
client
else
\
'Forbidden action.'
message
=
dict
(
uid
=
client
.
id
,
message
=
user_message
)
if
note
:
...
...
portal/service/general.py
View file @
964d92ba
...
...
@@ -262,7 +262,7 @@ def find_client(identifier: str, throws=False, client_type=None) -> Client:
query
=
Worker
.
query
.
filter
((
Worker
.
id
==
identifier
)
|
(
Worker
.
name
==
identifier
))
return
find_resource
(
resource
=
'
client
'
,
resource
=
'
permissions
'
,
identifier
=
identifier
,
query
=
query
,
throws
=
throws
...
...
@@ -298,4 +298,4 @@ def find_client_owner(client: Client) -> Union[User, Worker]:
return
find_user
(
client
.
id
)
if
client
.
type
==
ClientType
.
WORKER
:
return
find_worker
(
client
.
id
)
raise
UnauthorizedError
(
f
"[LOGIN] Unknown
client type
{
client
.
type
}
."
)
raise
UnauthorizedError
(
f
"[LOGIN] Unknown
permissions type
{
permissions
.
type
}
."
)
portal/service/groups.py
View file @
964d92ba
...
...
@@ -182,15 +182,15 @@ class GroupService:
"""List all groups
Args:
course(Course): Course instance
client
: Client instance
permissions
: Client instance
Returns(list): List of all groups
"""
perm_service
=
permissions
.
PermissionsService
(
course
=
course
)
if
perm_service
.
check
.
client
([
'view_course_full'
]):
if
perm_service
.
check
.
permissions
([
'view_course_full'
]):
return
course
.
groups
elif
perm_service
.
check
.
client
([
'view_course_limited'
]):
elif
perm_service
.
check
.
permissions
([
'view_course_limited'
]):
return
filters
.
filter_groups_from_course
(
course
=
course
,
user
=
perm_service
.
client
)
raise
ForbiddenError
(
perm_service
.
client
)
...
...
portal/service/permissions.py
View file @
964d92ba
...
...
@@ -34,7 +34,7 @@ class PermissionServiceCheck:
return
self
.
service
.
client
.
is_admin
return
False
def
client
(
self
,
permissions
)
->
bool
:
def
permissions
(
self
,
permissions
)
->
bool
:
log
.
debug
(
f
"[PERM] Client
{
self
.
service
.
client
.
id
}
in course "
f
"
{
self
.
service
.
course
.
codename
}
:
{
permissions
}
"
)
...
...
@@ -65,69 +65,79 @@ class PermissionServiceRequire:
def
sysadmin
(
self
):
self
.
any_check
(
self
.
service
.
check
.
sysadmin
())
def
client
(
self
,
permissions
):
self
.
any_check
(
self
.
service
.
check
.
client
(
permissions
))
def
permissions
(
self
,
permissions
):
self
.
any_check
(
self
.
service
.
check
.
permissions
(
permissions
))
def
any_check
(
self
,
*
checks
):
if
not
self
.
service
.
check
.
any_check
(
*
checks
):
raise
ForbiddenError
(
self
.
service
.
client
)
def
update_course
(
self
):
self
.
client
([
'update_course'
])
self
.
permissions
([
'update_course'
])
def
write_projects
(
self
):
self
.
client
([
'update_course'
,
'write_projects'
])
self
.
permissions
([
'update_course'
,
'write_projects'
])
def
write_roles
(
self
):
self
.
client
([
'update_course'
,
'write_roles'
])
self
.
permissions
([
'update_course'
,
'write_roles'
])
def
write_groups
(
self
):
self
.
client
([
'update_course'
,
'write_groups'
])
self
.
permissions
([
'update_course'
,
'write_groups'
])
def
view_course
(
self
):
self
.
client
([
'view_course_full'
,
'view_course_limited'
])
self
.
permissions
([
'view_course_full'
,
'view_course_limited'
])
def
belongs_to_group
(
self
,
group
):
checks
=
[
self
.
service
.
check
.
client
([
'view_course_full'
]),
(
self
.
service
.
check
.
client
([
'view_course_limited'
])
self
.
service
.
check
.
permissions
([
'view_course_full'
]),
(
self
.
service
.
check
.
permissions
([
'view_course_limited'
])
and
self
.
service
.
client_owner
in
group
.
users
)
]
self
.
any_check
(
*
checks
)
def
belongs_to_role
(
self
,
role
:
Role
):
checks
=
[
self
.
service
.
check
.
client
([
'view_course_full'
]),
(
self
.
service
.
check
.
client
([
'view_course_limited'
])
self
.
service
.
check
.
permissions
([
'view_course_full'
]),
(
self
.
service
.
check
.
permissions
([
'view_course_limited'
])
and
self
.
service
.
client_owner
in
role
.
clients
)
]
self
.
any_check
(
*
checks
)
def
read_submission
(
self
,
submission
):
checks
=
[
self
.
service
.
check
.
client
([
'read_submissions_all'
]),
self
.
service
.
check
.
permissions
([
'read_submissions_all'
]),
self
.
service
.
submission_access_group
(
submission
,
[
'read_submissions_groups'
]),
(
self
.
service
.
check
.
client
([
'read_submissions_own'
])
and
(
self
.
service
.
check
.
permissions
([
'read_submissions_own'
])
and
submission
.
user
==
self
.
service
.
client_owner
)
]
self
.
any_check
(
*
checks
)
def
read_submission_group
(
self
,
submission
):
checks
=
[
self
.
service
.
check
.
client
([
'read_submissions_all'
]),
self
.
service
.
check
.
permissions
([
'read_submissions_all'
]),
self
.
service
.
submission_access_group
(
submission
,
[
'read_submissions_groups'
])
]
self
.
any_check
(
*
checks
)
def
write_review_for_submission
(
self
,
submission
):
checks
=
[
self
.
service
.
check
.
client
([
'write_reviews_all'
]),
self
.
service
.
check
.
permissions
([
'write_reviews_all'
]),
self
.
service
.
submission_access_group
(
submission
,
[
'write_reviews_group'
]),
(
self
.
service
.
check
.
client
([
'write_reviews_own'
])
and
(
self
.
service
.
check
.
permissions
([
'write_reviews_own'
])
and
submission
.
user
==
self
.
service
.
client_owner
)
]
self
.
any_check
(
*
checks
)
def
create_submission
(
self
,
user
):
if
user
!=
self
.
service
.
client
:
self
.
permissions
([
'create_submissions_other'
])
user_service
=
PermissionsService
(
course
=
self
.
service
.
course
,
client
=
user
)
user_service
.
require
.
permissions
(
'create_submissions'
)
def
course_access_token
(
self
):
self
.
permissions
([
'handle_notes_access_token'
])
class
PermissionsService
:
def
__init__
(
self
,
client
=
None
,
course
=
None
):
...
...
@@ -157,14 +167,14 @@ class PermissionsService:
return
self
.
_course
def
get_effective_permissions
(
self
,
course_id
:
str
=
None
)
->
dict
:
"""Gets effective permissions for a
client
in course.
If no course is specified, returns the
client
's
"""Gets effective permissions for a
permissions
in course.
If no course is specified, returns the
permissions
's
effective permissions in all courses he is a part of.
Args:
course_id(str): Course ID
Returns(dict): Effective permissions for the
client
. Keys are course IDs, values
Returns(dict): Effective permissions for the
permissions
. Keys are course IDs, values
dictionaries of permissions with their values.
"""
course
=
general
.
find_course
(
course_id
,
throws
=
False
)
...
...
@@ -172,7 +182,7 @@ class PermissionsService:
return
self
.
build_effective_permissions
(
*
courses
)
def
build_effective_permissions
(
self
,
*
courses
)
->
dict
:
"""Builds effective permissions in a list of courses for the
client
"""Builds effective permissions in a list of courses for the
permissions
Args:
*courses: List of courses
...
...
@@ -185,7 +195,7 @@ class PermissionsService:
return
result
def
effective_permissions_for_course
(
self
,
course
:
Course
=
None
)
->
dict
:
"""Extracts effective permissions for a
client
in one course
"""Extracts effective permissions for a
permissions
in one course
Returns(dict): Effective permissions dictionary
"""
...
...
@@ -197,12 +207,12 @@ class PermissionsService:
if
not
key
.
startswith
(
"_"
)
and
key
not
in
FILTER_PERMISSION_ATTRS
:
result
[
key
]
=
result
.
get
(
key
)
or
value
log
.
debug
(
f
"[PERM] Effective permissions:
{
self
.
client
.
id
}
"
f
"[PERM] Effective permissions:
{
self
.
permissions
.
id
}
"
f
"in course
{
course
.
codename
}
:
{
result
}
"
)
return
result
def
submission_access_group
(
self
,
submission
,
perm
):
if
self
.
check
.
client
(
perm
):
if
self
.
check
.
permissions
(
perm
):
group_intersection
=
[
group
for
group
in
self
.
client
.
groups
if
submission
.
user
in
group
.
users
]
return
any
(
...
...
portal/service/projects.py
View file @
964d92ba
...
...
@@ -145,15 +145,15 @@ class ProjectService:
"""List of all projects
Args:
course(Course): Course instance
client
: Client instance
permissions
: Client instance
Returns(list): list of projects
"""
perm_service
=
permissions
.
PermissionsService
(
course
=
course
)
if
perm_service
.
check
.
client
([
'view_course_full'
]):
if
perm_service
.
check
.
permissions
([
'view_course_full'
]):
return
course
.
projects
elif
perm_service
.
check
.
client
([
'view_course_limited'
]):
elif
perm_service
.
check
.
permissions
([
'view_course_limited'
]):
return
filters
.
filter_projects_from_course
(
course
=
course
,
user
=
perm_service
.
client
)
raise
ForbiddenError
(
perm_service
.
client
)
...
...
portal/service/roles.py
View file @
964d92ba
...
...
@@ -101,14 +101,14 @@ class RoleService:
"""Finds all clients based on their ids
Args:
ids(List[str]): List of
client
ids
ids(List[str]): List of
permissions
ids
Returns(List[Client]): List of clients
"""
return
[
find_client
(
i
)
for
i
in
ids
]
def
update_clients_membership
(
self
,
data
:
dict
)
->
Role
:
"""Updates
client
membership in the role
"""Updates
permissions
membership in the role
Args:
data(dict): Data provided to update role membership
...
...
@@ -138,7 +138,7 @@ class RoleService:
return
clients
def
add_client
(
self
,
client
:
Client
):
"""Adds single
client
to the role
"""Adds single
permissions
to the role
Args:
client(Client): Client instance
Returns:
...
...
@@ -146,14 +146,14 @@ class RoleService:
if
client
not
in
self
.
role
.
clients
:
self
.
role
.
clients
.
append
(
client
)
write_entity
(
self
.
role
)
log
.
info
(
f
"[ADD] Client
{
client
.
id
}
to role "
log
.
info
(
f
"[ADD] Client
{
permissions
.
id
}
to role "
f
"
{
self
.
role
.
id
}
in course
{
self
.
role
.
course
.
id
}
."
)
else
:
log
.
info
(
f
"[ADD] Client
{
client
.
id
}
is already "
log
.
info
(
f
"[ADD] Client
{
permissions
.
id
}
is already "
f
"in role
{
self
.
role
.
id
}
in course
{
self
.
role
.
course
.
id
}
: no change."
)
def
remove_client
(
self
,
client
:
Client
)
->
Role
:
"""Removes single
client
from the role
"""Removes single
permissions
from the role
Args:
role(Role): Role instance
client(Client): Client instance
...
...
@@ -164,10 +164,10 @@ class RoleService:
self
.
role
.
clients
.
remove
(
client
)
write_entity
(
self
.
role
)
except
ValueError
:
raise
PortalAPIError
(
400
,
message
=
f
"Could not remove
client
{
client
.
id
}
"
raise
PortalAPIError
(
400
,
message
=
f
"Could not remove
permissions
{
permissions
.
id
}
"
f
"from role
{
self
.
role
.
id
}
in course
{
course
.
id
}
: "
f
"role does not contain
client
."
)
log
.
info
(
f
"[REMOVE] Client
{
client
.
id
}
from role "
f
"role does not contain
permissions
."
)
log
.
info
(
f
"[REMOVE] Client
{
permissions
.
id
}
from role "
f
"
{
self
.
role
.
id
}
in course
{
course
.
id
}
."
)
return
self
.
role
...
...
@@ -175,14 +175,14 @@ class RoleService:
"""List of all roles
Args:
course(Course): Course instance
client
(Client): Client instance
permissions
(Client): Client instance
Returns(list): List of roles
"""
perm_service
=
permissions
.
PermissionsService
(
course
=
course
)
if
perm_service
.
check
.
client
([
'view_course_full'
]):
if
perm_service
.
check
.
permissions
([
'view_course_full'
]):
return
course
.
roles
elif
perm_service
.
check
.
client
([
'view_course_limited'
]):
elif
perm_service
.
check
.
permissions
([
'view_course_limited'
]):
return
filter_roles_from_course
(
course
=
course
,
client
=
perm_service
.
client
)
raise
ForbiddenError
(
perm_service
.
client
)
portal/service/submissions.py
View file @
964d92ba
...
...
@@ -140,12 +140,12 @@ class SubmissionsService(object):
new_state
=
data
[
'state'
]
if
isinstance
(
client
,
User
)
and
new_state
!=
SubmissionState
.
CANCELLED
:
raise
errors
.
ForbiddenError
(
client
,
note
=
f
"User
{
client
.
id
}
cannot update "
note
=
f
"User
{
permissions
.
id
}
cannot update "
f
"state to other than CANCELLED."
)
self
.
submission
.
change_state
(
new_state
)
write_entity
(
self
.
submission
)
log
.
info
(
f
"[UPDATE] Submission state
{
self
.
submission
.
id
}
"
f
"by
{
client
.
id
}
to
{
self
.
submission
.
state
}
"
)
f
"by
{
permissions
.
id
}
to
{
self
.
submission
.
state
}
"
)
return
self
.
submission
def
cancel_submission
(
self
):
...
...
portal/service/users.py
View file @
964d92ba
...
...
@@ -110,7 +110,7 @@ class UserService:
return
self
.
user
def
update_password
(
self
,
data
:
dict
):
log
.
info
(
f
"[UPDATE] User password:
{
self
.
user
.
id
}
by
{
self
.
client
.
id
}
"
)
log
.
info
(
f
"[UPDATE] User password:
{
self
.
user
.
id
}
by
{
self
.
permissions
.
id
}
"
)
self
.
__require_param
(
data
,
'new_password'
)
if
self
.
client
==
self
.
user
and
not
self
.
user
.
is_admin
:
self
.
__check_old_password
(
data
)
...
...
@@ -127,7 +127,7 @@ class UserService:
raise
IncorrectCredentialsError
()