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
5b21d9fa
Verified
Commit
5b21d9fa
authored
Aug 15, 2018
by
Peter Stanko
Browse files
Permissions update - onlu sysadmin and component should be able to upload files
parent
5e9ea0ca
Pipeline
#12991
passed with stage
in 14 minutes and 45 seconds
Changes
11
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
app.py
View file @
5b21d9fa
...
...
@@ -160,10 +160,17 @@ def cli_submissions_cancel(sid):
@
submissions_cli
.
command
(
'list'
,
help
=
"List all submissions"
)
def
cli_submissions_
cancel
_all
():
def
cli_submissions_
list
_all
():
log
.
info
(
f
"[CMD] List all submissions"
)
manager
.
list_all_submissions
()
@
submissions_cli
.
command
(
'clean-all'
,
help
=
"Clean all submissions"
)
def
cli_submissions_list_all
():
log
.
info
(
f
"[CMD] Clean all submissions"
)
manager
.
clean_all_submissions
()
if
__name__
==
'__main__'
:
cli_run_devel
()
management/data/__init__.py
View file @
5b21d9fa
...
...
@@ -153,4 +153,10 @@ class DataManagement(object):
write_entity
(
submission
)
self
.
db
.
session
.
commit
()
def
clean_all_submissions
(
self
):
with
self
.
app
.
app_context
():
for
submission
in
Submission
.
query
.
all
():
Submission
.
query
.
filter_by
(
id
=
submission
.
id
).
delete
()
self
.
db
.
session
.
commit
()
portal/async_celery/tasks.py
View file @
5b21d9fa
...
...
@@ -32,7 +32,6 @@ def upload_results_to_storage(new_submission_id: str, path: str):
return
entity
@
celery_app
.
task
(
name
=
'clone-submission-files'
)
def
clone_submission_files
(
source_id
:
str
,
target_id
:
str
):
source
=
find_submission
(
source_id
)
...
...
portal/config.py
View file @
5b21d9fa
...
...
@@ -46,7 +46,7 @@ class DevelopmentConfig(Config):
DEBUG
=
True
CELERY_RESULT_BACKEND
=
'redis://localhost:6379/0'
BROKER_URL
=
'redis://localhost:6379/0'
PORTAL_STORAGE_BASE_DIR
=
tempfile
.
mkd
temp
()
PORTAL_STORAGE_BASE_DIR
=
f
"
{
tempfile
.
get
temp
dir
()
}
/kontr-portal"
PORTAL_STORAGE_TEST_FILES_DIR
=
f
"
{
PORTAL_STORAGE_BASE_DIR
}
/test-files"
PORTAL_STORAGE_WORKSPACE_DIR
=
f
"
{
PORTAL_STORAGE_BASE_DIR
}
/workspace"
PORTAL_STORAGE_SUBMISSIONS_DIR
=
f
"
{
PORTAL_STORAGE_BASE_DIR
}
/submissions"
...
...
portal/logging.py
View file @
5b21d9fa
...
...
@@ -27,7 +27,7 @@ LOGGERS = {
'tests'
:
{
'handlers'
:
[
'console'
],
'level'
:
'DEBUG'
,
'propagate'
:
True
},
'management'
:
{
'handlers'
:
[
'console'
],
'level'
:
'INFO'
,
'propagate'
:
True
},
'app'
:
{
'handlers'
:
[
'console'
],
'level'
:
'INFO'
,
'propagate'
:
True
},
'storage'
:
{
'handlers'
:
[
'console'
],
'level'
:
'
INFO
'
,
'propagate'
:
True
},
'storage'
:
{
'handlers'
:
[
'console'
],
'level'
:
'
DEBUG
'
,
'propagate'
:
True
},
}
LOGGING_CONF
=
{
...
...
portal/rest/errors.py
View file @
5b21d9fa
...
...
@@ -14,7 +14,7 @@ log = logging.getLogger(__name__)
def
load_errors
(
app
:
Flask
):
log
.
debug
(
"[
ERR] E
rror handlers loaded"
)
log
.
debug
(
"[
LOAD] Custom e
rror handlers loaded"
)
for
(
ex
,
func
)
in
rest_api
.
error_handlers
.
items
():
app
.
register_error_handler
(
ex
,
func
)
...
...
portal/rest/login.py
View file @
5b21d9fa
...
...
@@ -32,9 +32,7 @@ logout_schema = auth_namespace.model('LogoutSchema', {
@
jwt
.
user_claims_loader
def
add_claims_to_access_token
(
identity
):
data
=
'user'
if
general
.
find_component
(
identity
,
throws
=
False
):
data
=
'component'
data
=
'user'
if
User
.
query
.
filter_by
(
id
=
identity
).
first
()
else
'component'
return
dict
(
type
=
data
)
...
...
portal/rest/submissions.py
View file @
5b21d9fa
...
...
@@ -20,7 +20,7 @@ log = logging.getLogger(__name__)
def
submission_access_group
(
client
,
submission
,
course
,
perm
):
if
permissions
.
check_client
(
client
,
course
,
perm
):
group_intersection
=
[
group
for
group
in
client
.
groups
if
submission
.
user
in
group
]
group
for
group
in
client
.
groups
if
submission
.
user
in
group
.
users
]
return
any
(
group
in
submission
.
project
.
groups
for
group
in
group_intersection
)
return
False
...
...
@@ -183,14 +183,11 @@ class SubmissionResultFiles(Resource):
def
post
(
self
,
sid
:
str
):
client
=
auth
.
find_client
()
submission
=
general
.
find_submission
(
sid
)
course
=
submission
.
project
.
course
# authorization
checks
=
[
check_client
(
client
,
course
,
[
'read_submissions_all'
]),
submission_access_group
(
client
,
submission
,
course
,
[
'read_submissions_groups'
])
]
permissions
.
require_any_check
(
client
,
checks
=
checks
)
permissions
.
require_sysadmin
(
client
)
permissions
.
require_any_check
(
client
,
checks
=
[
permissions
.
check_sysadmin
(
client
),
permissions
.
check_component
(
client
)])
task
=
upload_results_to_storage
(
submission
)
return
{
'new_task'
:
task
}
...
...
portal/service/auth.py
View file @
5b21d9fa
...
...
@@ -115,6 +115,7 @@ def find_client() -> Union[User, Component]:
claims
=
get_jwt_claims
()
if
not
(
claims
or
claims
.
get
(
'type'
)):
raise
UnauthorizedError
(
note
=
"No type claim."
)
if
claims
[
'type'
]
==
'user'
:
client
=
__find_client_helper
(
identity
,
'user'
,
find_user
)
elif
claims
[
'type'
]
==
'component'
:
...
...
portal/service/permissions.py
View file @
5b21d9fa
...
...
@@ -43,10 +43,9 @@ def check_client(client: Union[Component, User],
Returns(bool): True if checks has passed
"""
check
=
(
check_component
(
component
=
client
)
or
check_user
(
user
=
client
,
course
=
course
,
permissions
=
permissions
))
return
check
if
isinstance
(
client
,
User
):
return
check_user
(
user
=
client
,
course
=
course
,
permissions
=
permissions
)
return
check_component
(
component
=
client
)
def
check_component
(
component
:
Component
)
->
bool
:
...
...
@@ -179,5 +178,5 @@ def effective_permissions_for_course(user: User, course: Course) -> dict:
result
[
key
]
=
result
.
get
(
key
)
or
value
log
.
debug
(
f
"[PERM] Effective permissions:
{
user
.
username
}
in course
{
course
.
codename
}
:
{
result
}
"
)
)
return
result
portal/service/submissions.py
View file @
5b21d9fa
...
...
@@ -143,11 +143,19 @@ def cancel_submission(submission: Submission):
def
send_zip
(
storage_submission
:
entities
.
Submission
):
return
flask
.
send_file
(
storage_submission
.
zip_path
)
path
=
storage_submission
.
zip_path
if
not
path
.
exists
():
raise
errors
.
PortalAPIError
(
400
,
f
"Requested path does not exist:
{
path
}
"
)
log
.
debug
(
f
"[SEND] Sending zip file for submission (
{
storage_submission
.
entity_id
}
):
{
path
}
"
)
return
flask
.
send_file
(
str
(
path
),
attachment_filename
=
path
.
name
)
def
send_selected_file
(
storage_submission
:
entities
.
Submission
,
path_query
:
str
):
return
flask
.
send_file
(
storage_submission
.
glob
(
path_query
))
path
=
storage_submission
.
base_dir
/
Path
(
path_query
)
if
not
path
.
exists
():
raise
errors
.
PortalAPIError
(
400
,
f
"Requested path does not exist:
{
path
}
"
)
log
.
debug
(
f
"[SEND] Sending file for submission (
{
storage_submission
.
entity_id
}
):
{
path
}
"
)
return
flask
.
send_file
(
str
(
path
))
def
send_file_or_zip
(
storage_entity
):
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment