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
b3dac4d5
Unverified
Commit
b3dac4d5
authored
Sep 16, 2018
by
Peter Stanko
Browse files
Refactor Schemas
parent
370b1540
Changes
12
Hide whitespace changes
Inline
Side-by-side
portal/rest/client.py
View file @
b3dac4d5
...
...
@@ -3,7 +3,7 @@ from flask_restplus import Namespace, Resource
from
portal
import
logger
from
portal.database.models
import
ClientType
from
portal.rest.schemas
import
user_schema
,
worker_schema
from
portal.rest.schemas
import
SCHEMAS
from
portal.service
import
permissions
client_namespace
=
Namespace
(
'client'
)
...
...
@@ -18,5 +18,5 @@ class ClientController(Resource):
def
get
(
self
):
perm_service
=
permissions
.
PermissionsService
()
client
=
perm_service
.
client_owner
schema
=
user_schema
if
client
.
type
==
ClientType
.
USER
else
worker_schema
schema
=
SCHEMAS
.
user
()
if
client
.
type
==
ClientType
.
USER
else
SCHEMAS
.
worker
()
return
schema
.
dump
(
client
)[
0
],
200
portal/rest/courses.py
View file @
b3dac4d5
...
...
@@ -4,7 +4,7 @@ from flask_restplus import Namespace, Resource
from
portal
import
logger
from
portal.rest
import
rest_helpers
from
portal.rest.schemas
import
course_import_schema
,
course_schema
,
courses_schema
,
users_schema
from
portal.rest.schemas
import
SCHEMAS
from
portal.service
import
permissions
from
portal.service.auth
import
find_client
from
portal.service.courses
import
CourseService
...
...
@@ -26,7 +26,7 @@ class CourseList(Resource):
permissions
.
PermissionsService
().
require
.
sysadmin
()
courses_list
=
CourseService
().
find_all_courses
()
return
courses_schema
.
dump
(
courses_list
)
return
SCHEMAS
.
dump
(
'courses'
,
courses_list
)
@
jwt_required
# @courses_namespace.response(200, 'Created course', model=course_schema)
...
...
@@ -34,10 +34,9 @@ class CourseList(Resource):
def
post
(
self
):
permissions
.
PermissionsService
().
require
.
sysadmin
()
data
=
rest_helpers
.
parse_request_data
(
course_schema
,
resource
=
'course'
,
action
=
'create'
)
data
=
rest_helpers
.
parse_request_data
(
resource
=
'course'
,
action
=
'create'
)
new_course
=
CourseService
().
create_course
(
**
data
)
return
course_schema
.
dump
(
new_course
)
[
0
]
,
201
return
SCHEMAS
.
dump
(
'course'
,
new_course
),
201
@
courses_namespace
.
route
(
'/<string:cid>'
)
...
...
@@ -54,11 +53,12 @@ class CourseResource(Resource):
# authorization
perm_service
=
permissions
.
PermissionsService
(
course
=
course
)
if
perm_service
.
check
.
permissions
([
'view_course_full'
]):
return
course_schema
.
dump
(
course
)
return
SCHEMAS
.
dump
(
'course'
,
course
)
elif
perm_service
.
check
.
permissions
([
'view_course_limited'
]):
dump
=
course_schema
.
dump
(
course
)
filtered_course
=
filter_course_dump
(
course
,
dump
.
data
,
client
)
# TODO: Refactor
dump
=
SCHEMAS
.
dump
(
'course'
,
course
)
filtered_course
=
filter_course_dump
(
course
,
dump
,
client
)
return
filtered_course
raise
ForbiddenError
(
client
=
client
)
...
...
@@ -80,9 +80,7 @@ class CourseResource(Resource):
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
update_course
()
data
=
rest_helpers
.
parse_request_data
(
schema
=
course_schema
,
action
=
'update'
,
resource
=
'course'
,
partial
=
True
)
data
=
rest_helpers
.
parse_request_data
(
action
=
'update'
,
resource
=
'course'
,
partial
=
True
)
CourseService
(
course
=
course
).
update_course
(
data
)
return
''
,
204
...
...
@@ -110,8 +108,7 @@ class CourseNotesToken(Resource):
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
course_access_token
()
json_data
=
rest_helpers
.
require_data
(
action
=
'update_notes_token'
,
resource
=
'course'
)
json_data
=
rest_helpers
.
require_data
(
action
=
'update_notes_token'
,
resource
=
'course'
)
CourseService
(
course
=
course
).
update_notes_token
(
json_data
[
'token'
])
return
''
,
204
...
...
@@ -131,7 +128,7 @@ class CourseImport(Resource):
permissions
.
PermissionsService
(
course
=
course
).
require
.
update_course
()
data
=
rest_helpers
.
parse_request_data
(
course_import
_schema
,
action
=
'import'
,
resource
=
'course'
schema
=
SCHEMAS
.
course_import
,
action
=
'import'
,
resource
=
'course'
)
source_course
=
find_course
(
data
[
'source_course'
])
if
source_course
==
course
:
...
...
@@ -141,14 +138,13 @@ class CourseImport(Resource):
config
=
data
[
'config'
]
copied_course
=
CourseService
(
course
=
course
).
copy_course
(
course
,
config
)
return
course_schema
.
dump
(
copied_course
)
[
0
]
return
SCHEMAS
.
dump
(
'course'
,
copied_course
)
@
courses_namespace
.
route
(
'/<string:cid>/users'
)
@
courses_namespace
.
param
(
'cid'
,
'Course id'
)
@
courses_namespace
.
response
(
404
,
'Course not found'
)
class
CourseUsers
(
Resource
):
@
jwt_required
# @courses_namespace.response(200, 'Users in the course', model=users_schema)
@
courses_namespace
.
response
(
403
,
'Not allowed to see users in the course'
)
...
...
@@ -158,4 +154,4 @@ class CourseUsers(Resource):
group_ids
=
request
.
args
.
getlist
(
'group'
)
role_ids
=
request
.
args
.
getlist
(
'role'
)
users
=
CourseService
(
course
=
course
).
get_users_filtered
(
group_ids
,
role_ids
)
return
users_schema
.
dump
(
users
)
[
0
]
return
SCHEMAS
.
dump
(
'users'
,
users
)
portal/rest/groups.py
View file @
b3dac4d5
...
...
@@ -4,8 +4,7 @@ from flask_restplus import Namespace, Resource
from
portal
import
logger
from
portal.rest
import
rest_helpers
from
portal.rest.schemas
import
client_list_update_schema
,
group_import_schema
,
group_schema
,
\
groups_schema
,
projects_schema
,
users_schema
from
portal.rest.schemas
import
SCHEMAS
from
portal.service
import
general
,
permissions
from
portal.service.groups
import
GroupService
...
...
@@ -23,7 +22,7 @@ class GroupsList(Resource):
def
get
(
self
,
cid
:
str
):
course
=
general
.
find_course
(
cid
)
groups
=
GroupService
().
list_groups
(
course
)
return
groups_schema
.
dump
(
groups
)
[
0
]
return
SCHEMAS
.
dump
(
'groups'
,
groups
)
@
jwt_required
# @groups_namespace.response(201, 'Group created', model=group_schema)
...
...
@@ -33,10 +32,10 @@ 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
(
action
=
'create'
,
resource
=
'group'
)
new_group
=
GroupService
().
create_group
(
course
,
**
data
)
return
group_schema
.
dump
(
new_group
)
[
0
]
,
201
return
SCHEMAS
.
dump
(
'group'
,
new_group
),
201
@
groups_namespace
.
route
(
'/courses/<string:cid>/groups/<string:gid>'
)
...
...
@@ -54,7 +53,7 @@ class GroupResource(Resource):
permissions
.
PermissionsService
(
course
=
course
).
require
.
view_course
()
group
=
general
.
find_group
(
course
,
gid
)
return
group_schema
.
dump
(
group
)
return
SCHEMAS
.
dump
(
'group'
,
group
)
@
jwt_required
@
groups_namespace
.
response
(
204
,
'Group deleted'
)
...
...
@@ -76,10 +75,7 @@ class GroupResource(Resource):
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
write_groups
()
data
=
rest_helpers
.
parse_request_data
(
group_schema
,
action
=
'update'
,
resource
=
'group'
,
partial
=
True
)
data
=
rest_helpers
.
parse_request_data
(
action
=
'update'
,
resource
=
'group'
,
partial
=
True
)
group
=
general
.
find_group
(
course
,
gid
)
GroupService
(
group
).
update_group
(
data
)
return
''
,
204
...
...
@@ -101,7 +97,7 @@ class GroupUsersList(Resource):
permissions
.
PermissionsService
(
course
=
course
).
require
.
belongs_to_group
(
group
)
users
=
GroupService
(
group
).
find_users_by_role
(
course
,
role_id
)
return
users_schema
.
dump
(
users
)
return
SCHEMAS
.
dump
(
'users'
,
users
)
@
jwt_required
@
groups_namespace
.
response
(
204
,
'User
\'
s list updated'
)
...
...
@@ -112,7 +108,7 @@ class GroupUsersList(Resource):
permissions
.
PermissionsService
(
course
=
course
).
require
.
write_groups
()
data
=
rest_helpers
.
parse_request_data
(
client_list_update
_schema
,
action
=
'update'
,
resource
=
'group_membership'
schema
=
SCHEMAS
.
client_list_update
,
action
=
'update'
,
resource
=
'group_membership'
)
group
=
general
.
find_group
(
course
,
gid
)
...
...
@@ -173,7 +169,7 @@ class GroupProjectsList(Resource):
permissions
.
PermissionsService
(
course
=
course
).
require
.
belongs_to_group
(
group
)
projects
=
GroupService
(
group
).
find_projects
()
return
projects_schema
.
dump
(
projects
)
return
SCHEMAS
.
dump
(
'projects'
,
projects
)
@
groups_namespace
.
route
(
...
...
@@ -228,7 +224,7 @@ class GroupImport(Resource):
# authorization
permissions
.
PermissionsService
(
course
=
target_course
).
require
.
write_groups
()
data
=
rest_helpers
.
parse_request_data
(
group_import
_schema
,
action
=
'import'
,
resource
=
'group'
schema
=
SCHEMAS
.
group_import
,
action
=
'import'
,
resource
=
'group'
)
new_group
=
GroupService
().
import_group
(
data
,
target_course
)
return
group_schema
.
dump
(
new_group
),
201
return
SCHEMAS
.
dump
(
'group'
,
new_group
),
201
portal/rest/projects.py
View file @
b3dac4d5
...
...
@@ -5,8 +5,7 @@ from flask_restplus import Namespace, Resource
from
portal
import
logger
from
portal.database.models
import
ClientType
,
ProjectState
from
portal.rest
import
rest_helpers
from
portal.rest.schemas
import
config_schema
,
config_schema_reduced
,
project_schema
,
\
projects_schema
,
submission_create_schema
,
submission_schema
,
submissions_schema
from
portal.rest.schemas
import
SCHEMAS
from
portal.service
import
auth
,
general
,
permissions
from
portal.service.errors
import
ForbiddenError
,
SubmissionRefusedError
from
portal.service.projects
import
ProjectService
...
...
@@ -29,7 +28,7 @@ class ProjectsList(Resource):
def
get
(
self
,
cid
:
str
):
course
=
general
.
find_course
(
cid
)
projects
=
ProjectService
().
list_projects
(
course
)
return
projects_schema
.
dump
(
projects
)
return
SCHEMAS
.
dump
(
'projects'
,
projects
)
@
jwt_required
@
projects_namespace
.
response
(
404
,
'Course not found'
)
...
...
@@ -39,12 +38,10 @@ class ProjectsList(Resource):
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
update_course
()
data
=
rest_helpers
.
parse_request_data
(
project_schema
,
action
=
'create'
,
resource
=
'project'
)
data
=
rest_helpers
.
parse_request_data
(
action
=
'create'
,
resource
=
'project'
)
new_project
=
ProjectService
().
create_project
(
course
,
data
)
return
project_schema
.
dump
(
new_project
)
[
0
]
,
201
return
SCHEMAS
.
dump
(
'project'
,
new_project
),
201
@
projects_namespace
.
route
(
'/courses/<string:cid>/projects/<string:pid>'
)
...
...
@@ -62,7 +59,7 @@ class ProjectResource(Resource):
permissions
.
PermissionsService
(
course
=
course
).
require
.
view_course
()
project
=
general
.
find_project
(
course
,
pid
)
return
project_schema
.
dump
(
project
)
return
SCHEMAS
.
dump
(
'project'
,
project
)
@
jwt_required
@
projects_namespace
.
response
(
204
,
'Project deleted'
)
...
...
@@ -84,9 +81,7 @@ class ProjectResource(Resource):
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
write_projects
()
data
=
rest_helpers
.
parse_request_data
(
project_schema
,
action
=
'update'
,
resource
=
'project'
,
partial
=
True
)
data
=
rest_helpers
.
parse_request_data
(
action
=
'update'
,
resource
=
'project'
,
partial
=
True
)
project
=
general
.
find_project
(
course
,
pid
)
ProjectService
(
project
).
update_project
(
data
)
...
...
@@ -116,10 +111,7 @@ class ProjectConfigResource(Resource):
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
write_projects
()
data
=
rest_helpers
.
parse_request_data
(
config_schema
,
action
=
'update'
,
resource
=
'project_config'
)
data
=
rest_helpers
.
parse_request_data
(
action
=
'update'
,
resource
=
'config'
)
project
=
general
.
find_project
(
course
,
pid
)
ProjectService
(
project
).
update_project_config
(
data
)
return
''
,
204
...
...
@@ -160,7 +152,7 @@ class ProjectSubmissions(Resource):
user_id
=
request
.
args
.
get
(
'user'
)
project
=
general
.
find_project
(
course
,
pid
)
submissions
=
ProjectService
(
project
).
find_project_submissions
(
user_id
)
return
submissions_schema
.
dump
(
submissions
)
return
SCHEMAS
.
dump
(
'submissions'
,
submissions
)
@
jwt_required
# @projects_namespace.response(201, 'Project submission create', model=submission_schema)
...
...
@@ -177,7 +169,7 @@ class ProjectSubmissions(Resource):
_check_submission_create
(
user
,
project
)
data
=
rest_helpers
.
parse_request_data
(
submission_create
_schema
,
action
=
'create'
,
resource
=
'submission'
schema
=
SCHEMAS
.
submission_create
,
action
=
'create'
,
resource
=
'submission'
)
log
.
debug
(
f
"[REST] Create submission:
{
data
}
"
)
...
...
@@ -188,7 +180,7 @@ class ProjectSubmissions(Resource):
project
=
project
,
submission_params
=
data
)
return
submission_schema
.
dump
(
new_submission
)
[
0
]
,
201
return
SCHEMAS
.
dump
(
'submission'
,
new_submission
),
201
@
projects_namespace
.
route
(
'/courses/<string:cid>/projects/<string:pid>/files'
)
...
...
@@ -218,8 +210,8 @@ def _check_submission_create(client, project):
def
get_config_schema_based_on_permissions
(
course
):
perm_service
=
permissions
.
PermissionsService
(
course
=
course
)
if
perm_service
.
check
.
permissions
([
'view_course_full'
]):
return
config_schema
return
SCHEMAS
.
config
()
elif
perm_service
.
check
.
permissions
([
'view_course_limited'
]):
return
config_schema
_reduced
return
SCHEMAS
.
config
_reduced
()
else
:
raise
ForbiddenError
(
perm_service
.
client
)
portal/rest/rest_helpers.py
View file @
b3dac4d5
...
...
@@ -4,10 +4,12 @@ Helpers to work and process the rest requests and responses
from
flask
import
request
from
portal.rest.schemas
import
SCHEMAS
from
portal.service.errors
import
DataMissingError
def
parse_request_data
(
schema
,
action
:
str
,
resource
:
str
,
partial
=
False
)
->
dict
:
def
parse_request_data
(
schema
=
None
,
action
:
str
=
None
,
resource
:
str
=
None
,
partial
=
False
)
->
dict
:
"""Parses the request data using schema
Args:
schema(Schema): Resource schema
...
...
@@ -18,6 +20,10 @@ def parse_request_data(schema, action: str, resource: str, partial=False) -> dic
Returns(dict): Parsed dictionary
"""
if
schema
is
None
:
schema
=
getattr
(
SCHEMAS
,
resource
)
if
callable
(
schema
):
schema
=
schema
()
json_data
=
require_data
(
action
,
resource
=
resource
)
return
schema
.
load
(
json_data
,
partial
=
partial
)[
0
]
...
...
portal/rest/roles.py
View file @
b3dac4d5
...
...
@@ -5,8 +5,7 @@ from flask_restplus import Namespace, Resource
from
portal
import
logger
from
portal.database.models
import
ClientType
from
portal.rest
import
rest_helpers
from
portal.rest.schemas
import
client_list_update_schema
,
permissions_schema
,
role_schema
,
\
roles_schema
,
users_schema
from
portal.rest.schemas
import
SCHEMAS
from
portal.service
import
general
,
permissions
from
portal.service.roles
import
RoleService
...
...
@@ -23,7 +22,7 @@ class RoleList(Resource):
def
get
(
self
,
cid
):
course
=
general
.
find_course
(
cid
)
roles
=
RoleService
().
list_roles
(
course
)
return
roles_schema
.
dump
(
roles
)
[
0
]
return
SCHEMAS
.
dump
(
'roles'
,
roles
)
@
jwt_required
# @roles_namespace.response(201, 'Role created', model=role_schema)
...
...
@@ -32,11 +31,9 @@ class RoleList(Resource):
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
update_course
()
data
=
rest_helpers
.
parse_request_data
(
role_schema
,
action
=
'create'
,
resource
=
'role'
)
data
=
rest_helpers
.
parse_request_data
(
action
=
'create'
,
resource
=
'role'
)
new_role
=
RoleService
().
create_role
(
course
,
**
data
)
return
role_schema
.
dump
(
new_role
)
[
0
]
,
201
return
SCHEMAS
.
dump
(
'role'
,
new_role
),
201
@
roles_namespace
.
route
(
'/courses/<string:cid>/roles/<string:rid>'
)
...
...
@@ -53,7 +50,7 @@ class RoleResource(Resource):
permissions
.
PermissionsService
(
course
=
course
).
require
.
view_course
()
role
=
general
.
find_role
(
course
,
rid
)
return
role_schema
.
dump
(
role
)
return
SCHEMAS
.
dump
(
'role'
,
role
)
@
jwt_required
@
roles_namespace
.
response
(
204
,
'Deleted role'
)
...
...
@@ -73,9 +70,7 @@ class RoleResource(Resource):
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
write_roles
()
data
=
rest_helpers
.
parse_request_data
(
role_schema
,
action
=
'update'
,
resource
=
'role'
,
partial
=
True
)
data
=
rest_helpers
.
parse_request_data
(
action
=
'update'
,
resource
=
'role'
,
partial
=
True
)
role
=
general
.
find_role
(
course
,
rid
)
RoleService
(
role
).
update_role
(
data
)
...
...
@@ -88,7 +83,6 @@ class RoleResource(Resource):
@
roles_namespace
.
response
(
404
,
'Course not found'
)
@
roles_namespace
.
response
(
404
,
'Role not found'
)
class
RolePermissions
(
Resource
):
@
jwt_required
# @roles_namespace.response(200, 'Get permissions for role', model=permissions_schema)
def
get
(
self
,
cid
:
str
,
rid
:
str
):
...
...
@@ -98,7 +92,7 @@ class RolePermissions(Resource):
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
belongs_to_role
(
role
)
return
permissions_schema
.
dump
(
role
.
permissions
)
return
SCHEMAS
.
dump
(
'permissions'
,
role
.
permissions
)
@
jwt_required
# @roles_namespace.response(204, 'Update permissions for course', model=permissions_schema)
...
...
@@ -107,13 +101,11 @@ class RolePermissions(Resource):
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
write_roles
()
data
=
rest_helpers
.
parse_request_data
(
permissions_schema
,
action
=
'update'
,
resource
=
'role_permissions'
)
data
=
rest_helpers
.
parse_request_data
(
action
=
'update'
,
resource
=
'permissions'
)
role
=
general
.
find_role
(
course
,
rid
)
RoleService
(
role
).
update_permissions
(
data
)
return
permissions_schema
.
dump
(
role
.
permissions
),
20
4
return
SCHEMAS
.
dump
(
'permissions'
,
role
.
permissions
),
20
0
@
roles_namespace
.
route
(
'/courses/<string:cid>/roles/<string:rid>/clients'
)
...
...
@@ -132,8 +124,8 @@ class RoleUsersList(Resource):
permissions
.
PermissionsService
(
course
=
course
).
require
.
belongs_to_role
(
role
)
return
users_schema
.
dump
(
[
client
for
client
in
role
.
clients
if
client
.
type
==
ClientType
[
type
.
upper
()]]
)
users
=
[
client
for
client
in
role
.
clients
if
client
.
type
==
ClientType
[
type
.
upper
()]]
return
SCHEMAS
.
dump
(
'users'
,
users
)
@
jwt_required
@
roles_namespace
.
response
(
204
,
'Updates users membership in role'
)
...
...
@@ -143,7 +135,7 @@ class RoleUsersList(Resource):
permissions
.
PermissionsService
(
course
=
course
).
require
.
write_roles
()
data
=
rest_helpers
.
parse_request_data
(
client_list_update
_schema
,
action
=
'update'
,
resource
=
'role_membership'
schema
=
SCHEMAS
.
client_list_update
,
action
=
'update'
,
resource
=
'role_membership'
)
# everything from users_add is added, THEN everything from users_remove
...
...
portal/rest/schemas.py
View file @
b3dac4d5
"""
Schemas used to serialize/deserialize and validate of the models in the DB
"""
import
functools
from
marshmallow
import
Schema
,
ValidationError
,
fields
,
validates_schema
from
marshmallow_enum
import
EnumField
from
portal.database.models
import
ProjectState
,
SubmissionState
,
WorkerState
from
portal.database.models
import
ClientType
,
ProjectState
,
SubmissionState
,
WorkerState
class
NestedCollection
:
ENTITIES
=
{
'Role'
:
(
'id'
,
'codename'
,
'course.id'
),
'Group'
:
(
'id'
,
'codename'
,
'course.id'
),
'Project'
:
(
'id'
,
'codename'
,
'course.id'
),
'Course'
:
(
'id'
,
'codename'
),
'User'
:
(
'id'
,
'username'
,
'uco'
,
'codename'
),
'Worker'
:
(
'id'
,
'codename'
,
'name'
),
'Client'
:
(
'id'
,
'type'
,
'name'
,
'codename'
),
'Component'
:
(
'id'
,
'name'
,
'type'
),
'Submission'
:
(
'id'
,
'state'
,
'user.id'
,
'user.username'
,
'project.id'
,
'project.codename'
,
'project.course.id'
,
'project.course.codename'
,
'created_at'
,
'updated_at'
),
'ReviewItem'
:
(
'id'
,
'review.id'
,
'line'
,
'content'
,
'file'
,
'user.id'
),
'Secret'
:
(
'id'
,
'name'
,
'expires_at'
)
}
def
__init__
(
self
,
mod_name
):
self
.
mod_name
=
mod_name
self
.
collection
=
{}
...
...
@@ -38,6 +57,7 @@ class NestedCollection:
def
_set_nested_and_list
(
self
,
schema_name
,
params
):
self
.
_set_nested
(
schema_name
=
schema_name
,
params
=
params
)
# List version
self
.
_set_nested
(
schema_name
=
schema_name
,
params
=
params
,
many
=
True
)
def
__build_nested
(
self
):
...
...
@@ -46,22 +66,7 @@ class NestedCollection:
@
property
def
entities
(
self
):
return
{
'Role'
:
(
'id'
,
'codename'
,
'course.id'
),
'Group'
:
(
'id'
,
'codename'
,
'course.id'
),
'Project'
:
(
'id'
,
'codename'
,
'course.id'
),
'Course'
:
(
'id'
,
'codename'
),
'User'
:
(
'id'
,
'username'
,
'uco'
,
'codename'
),
'Worker'
:
(
'id'
,
'codename'
,
'name'
),
'Client'
:
(
'id'
,
'type'
,
'name'
,
'codename'
),
'Component'
:
(
'id'
,
'name'
,
'type'
),
'Submission'
:
(
'id'
,
'state'
,
'user.id'
,
'user.username'
,
'project.id'
,
'project.codename'
,
'project.course.id'
,
'project.course.codename'
,
'created_at'
,
'updated_at'
),
'ReviewItem'
:
(
'id'
,
'review.id'
,
'line'
,
'content'
,
'file'
,
'user.id'
),
'Secret'
:
(
'id'
,
'name'
,
'expires_at'
)
}
return
self
.
__class__
.
ENTITIES
def
get
(
self
,
name
):
return
self
.
collection
[
name
]
...
...
@@ -158,7 +163,7 @@ class SubmissionCreateSchema(Schema):
"""Submission Create Schema
"""
file_params
=
NESTED
(
'SubmissionFileParams'
,
required
=
True
)
project_params
=
fields
.
Dict
()
project_params
=
fields
.
Dict
(
required
=
False
,
allow_none
=
True
)
class
ProjectSchema
(
BaseSchema
,
NamedSchema
,
Schema
):
...
...
@@ -202,7 +207,7 @@ class RoleSchema(BaseSchema, NamedSchema, Schema):
class
ClientSchema
(
BaseSchema
,
Schema
):
type
=
fields
.
Str
(
)
type
=
EnumField
(
ClientType
,
by_value
=
True
)
class
RolePermissionsSchema
(
BaseSchema
,
Schema
):
...
...
@@ -330,6 +335,17 @@ class GroupImportSchema(Schema):
with_users
=
fields
.
Str
()
class
RoleImportSchema
(
Schema
):
source_course
=
fields
.
Str
()
source_role
=
fields
.
Str
()
with_users
=
fields
.
Str
()
class
ProjectImportSchema
(
Schema
):
source_course
=
fields
.
Str
()
source_project
=
fields
.
Str
()
class
NotificationSendToSchema
(
Schema
):
"""Notification Send To Schema
"""
...
...
@@ -358,42 +374,177 @@ class SubmissionResultSchema(Schema):
# pylint: enable=too-few-public-methods
ALWAYS_ALLOWED
=
[
'updated_at'
,
'created_at'
,
'id'
]
CODENAME_W_DESC
=
[
*
ALWAYS_ALLOWED
,
'name'
,
'codename'
,
'description'
]
user_schema
=
UserSchema
(
strict
=
True
)
user_schema_reduced
=
UserSchema
(
strict
=
True
,
only
=
(
*
ALWAYS_ALLOWED
,
'username'
,
'uco'
,
'email'
,
'name'
))
users_schema
=
UserSchema
(
many
=
True
,
only
=
(
*
ALWAYS_ALLOWED
,
'username'
,
'uco'
,
'email'
))
password_change_schema
=
PasswordChangeSchema
()
submission_schema
=
SubmissionSchema
()
submissions_schema
=
SubmissionSchema
(
many
=
True
,
only
=
(
*
ALWAYS_ALLOWED
,
'state'
,
'project'
,
'scheduled_for'
,
'user'
)
)
submission_create_schema
=
SubmissionCreateSchema
()
submission_state_schema
=
SubmissionSchema
(
only
=
(
'state'
,))
reviews_schema
=
ReviewSchema
(
many
=
True
)
review_schema
=
ReviewSchema
()
role_schema
=
RoleSchema
(
strict
=
True
)
roles_schema
=
RoleSchema
(
many
=
True
,
only
=
(
*
CODENAME_W_DESC
,
'course'
))
permissions_schema
=
RolePermissionsSchema
()
course_schema
=
CourseSchema
(
strict
=
True
)
course_schema_reduced
=
CourseSchema
(
strict
=
True
,
only
=
(
*
CODENAME_W_DESC
,))
courses_schema
=
CourseSchema
(
many
=
True
,
only
=
(
*
CODENAME_W_DESC
,))
course_import_schema
=
CourseImportSchema
(
strict
=
True
)
group_schema
=
GroupSchema
(
strict
=
True
)
groups_schema
=
GroupSchema
(
many
=
True
,
only
=
(
*
CODENAME_W_DESC
,
'course'
))
project_schema
=
ProjectSchema
(
strict
=
True
)
projects_schema
=
ProjectSchema
(
many
=
True
,
only
=
(
*
CODENAME_W_DESC
,
'course'
))
config_schema
=
ProjectConfigSchema
()
config_schema_reduced
=
ProjectConfigSchema
(
only
=
(
'id'
,
'project'
,
'submissions_allowed_from'
,
'submissions_allowed_to'
,
'file_whitelist'
))
client_list_update_schema
=
ClientListUpdateSchema
(
strict
=
True
)
group_import_schema
=
GroupImportSchema
(
strict
=
True
)
worker_schema
=
WorkerSchema
(
strict
=
True
)
workers_schema
=
WorkerSchema
(
strict
=
True
,
many
=
True
)
submission_result_schema
=
SubmissionResultSchema
(
strict
=
True
)
secrets_schema
=
SecretSchema
(
strict
=
True
,
many
=
True
,
only
=
(
*
ALWAYS_ALLOWED
,
'name'
,
'expires_at'
))
secret_schema
=
SecretSchema
(
strict
=
True
,
only
=
(
*
ALWAYS_ALLOWED
,
'name'
,
'expires_at'
))
def
fn_name
(
func
):
@
functools
.
wraps
(
func
)
def
__wrap
(
*
args
,
**
kwargs
):
return
func
(
*
args
,
select_params
=
func
.
__name__
,
**
kwargs
)
return
__wrap
class
Schemas
:
ALWAYS_ALLOWED
=
[
'updated_at'
,
'created_at'
,
'id'
]
CODENAME_W_DESC
=
[
*
ALWAYS_ALLOWED
,
'name'
,
'codename'
,
'description'
]
ENT_W_COURSE
=
(
*
CODENAME_W_DESC
,
'course'
)
PARAMS
=
{
'user_reduced'
:
(
*
ALWAYS_ALLOWED
,
'username'
,
'uco'
,
'email'
,
'name'
),
'users'
:
(
*
ALWAYS_ALLOWED
,
'username'
,
'uco'
,
'email'
),
'submissions'
:
(
*
ALWAYS_ALLOWED
,
'state'
,
'project'
,
'scheduled_for'
,
'user'
),
'submission_state'
:
(
*
ALWAYS_ALLOWED
,
'state'
),
'roles'
:
ENT_W_COURSE
,
'groups'
:
ENT_W_COURSE
,
'projects'
:
ENT_W_COURSE
,
'course_reduced'
:
(
*
CODENAME_W_DESC
,),
'courses'
:
(
*
CODENAME_W_DESC
,),
'config_reduced'
:
(
*
ALWAYS_ALLOWED
,
'project'
,
'submissions_allowed_from'
,
'submissions_allowed_to'
,
'file_whitelist'
),
'secrets'
:
(
*
ALWAYS_ALLOWED
,
'name'
,
'expires_at'
),
'secret'
:
(
*
ALWAYS_ALLOWED
,
'name'
,
'expires_at'
)
}
def
__get_schema
(
self
,
schema_klass
,
select_params
=
None
,
only
=
None
,
strict
=
True
,
**
kwargs
):
if
only
is
None
:
only
=
self
.
_select_params
(
select_params
)
params
=
{
'strict'
:
strict
,
**
kwargs
}
if
only
is
not
None
: