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
6b8f2b86
Verified
Commit
6b8f2b86
authored
Oct 06, 2018
by
Peter Stanko
Browse files
List of clients in the course
parent
6f057659
Changes
9
Hide whitespace changes
Inline
Side-by-side
portal/config.py
View file @
6b8f2b86
...
...
@@ -94,6 +94,7 @@ class TestConfig(Config):
BROKER_URL
=
'redis://'
CELERY_RESULT_BACKEND
=
BROKER_URL
PORTAL_LOG_CONFIG
=
False
GIT_REPO_BASE
=
os
.
getenv
(
'GIT_REPO_BASE'
,
f
"git@gitlab.local"
)
# pylint: enable=too-few-public-methods
...
...
portal/database/models.py
View file @
6b8f2b86
...
...
@@ -392,7 +392,7 @@ class Course(db.Model, EntityBase, NamedMixin):
.
join
(
User
.
roles
).
filter
((
Role
.
id
==
role
.
id
)
&
(
Role
.
course
==
self
))
\
.
all
()
def
get_
user
s_filtered
(
self
,
groups
:
List
[
'Group'
],
roles
:
List
[
'Role'
]):
def
get_
client
s_filtered
(
self
,
groups
:
List
[
'Group'
],
roles
:
List
[
'Role'
]):
"""Gets all users in the course who are members of at least one of
the provided groups and have at least one of the specified roles.
...
...
@@ -406,13 +406,13 @@ class Course(db.Model, EntityBase, NamedMixin):
(are in at least one group AND have at least one role).
"""
query
=
User
.
query
.
join
(
User
.
roles
).
filter
(
Role
.
course_id
==
self
.
id
)
query
=
Client
.
query
.
join
(
Client
.
roles
).
filter
(
Role
.
course_id
==
self
.
id
)
if
roles
:
role_ids
=
[
role
.
id
for
role
in
roles
]
query
=
query
.
filter
(
Role
.
id
.
in_
(
role_ids
))
if
groups
:
group_ids
=
[
group
.
id
for
group
in
groups
]
query
=
query
.
join
(
User
.
groups
).
filter
(
Group
.
id
.
in_
(
group_ids
)).
filter
(
query
=
query
.
join
(
Client
.
groups
).
filter
(
Group
.
id
.
in_
(
group_ids
)).
filter
(
Group
.
course_id
==
self
.
id
)
return
query
.
all
()
...
...
portal/rest/courses.py
View file @
6b8f2b86
...
...
@@ -138,10 +138,10 @@ class CourseImport(CustomResource):
return
SCHEMAS
.
dump
(
'course'
,
copied_course
)
@
courses_namespace
.
route
(
'/<string:cid>/
user
s'
)
@
courses_namespace
.
route
(
'/<string:cid>/
client
s'
)
@
courses_namespace
.
param
(
'cid'
,
'Course id'
)
@
courses_namespace
.
response
(
404
,
'Course not found'
)
class
Course
User
s
(
CustomResource
):
class
Course
Client
s
(
CustomResource
):
@
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'
)
...
...
@@ -150,5 +150,5 @@ class CourseUsers(CustomResource):
self
.
permissions
(
course
=
course
).
require
.
permissions
([
'view_course_full'
])
group_ids
=
request
.
args
.
getlist
(
'group'
)
role_ids
=
request
.
args
.
getlist
(
'role'
)
users
=
self
.
rest
.
courses
(
course
).
get_
user
s_filtered
(
group_ids
,
role_ids
)
users
=
self
.
rest
.
courses
(
course
).
get_
client
s_filtered
(
group_ids
,
role_ids
)
return
SCHEMAS
.
dump
(
'users'
,
users
)
portal/rest/schemas.py
View file @
6b8f2b86
...
...
@@ -383,7 +383,7 @@ class Schemas:
'user_reduced'
:
(
*
ALWAYS_ALLOWED
,
'username'
,
'uco'
,
'email'
,
'name'
),
'users'
:
(
*
ALWAYS_ALLOWED
,
'username'
,
'uco'
,
'email'
),
'submissions'
:
(
*
ALWAYS_ALLOWED
,
'course'
,
'state'
,
'project'
,
'scheduled_for'
,
'user'
),
'submission_state'
:
(
*
ALWAYS_ALLOWED
,
'state'
),
'submission_state'
:
(
*
ALWAYS_ALLOWED
,
'state'
,
'parameters'
,
'scheduled_for'
),
'roles'
:
ENT_W_COURSE
,
'groups'
:
ENT_W_COURSE
,
'projects'
:
ENT_W_COURSE
,
...
...
portal/service/courses.py
View file @
6b8f2b86
...
...
@@ -76,14 +76,13 @@ class CourseService(GeneralService):
log
.
info
(
f
"[UPDATE] Notes access token
{
self
.
course
.
log_name
}
:
{
token
}
"
)
return
self
.
course
def
get_
user
s_filtered
(
self
,
groups
:
List
[
str
],
roles
:
List
[
str
])
->
List
[
User
]:
def
get_
client
s_filtered
(
self
,
groups
:
List
[
str
],
roles
:
List
[
str
])
->
List
[
User
]:
"""Get all users for course filtered
Args:
groups(list): Group names list
roles(list): Role names list
Returns(List[User]):
"""
groups_entities
=
Group
.
query
.
filter
(
Group
.
id
.
in_
(
groups
)).
all
()
roles_entities
=
Role
.
query
.
filter
(
Role
.
id
.
in_
(
roles
)).
all
()
return
self
.
course
.
get_users_filtered
(
groups_entities
,
roles_entities
)
groups_entities
=
Group
.
query
.
filter
(
Group
.
id
.
in_
(
groups
)).
all
()
if
groups
else
None
roles_entities
=
Role
.
query
.
filter
(
Role
.
id
.
in_
(
roles
)).
all
()
if
roles
else
None
return
self
.
course
.
get_clients_filtered
(
groups_entities
,
roles_entities
)
portal/service/general.py
View file @
6b8f2b86
...
...
@@ -24,6 +24,10 @@ class GeneralService:
self
.
_rest_service
:
RestService
=
rest_service
self
.
_entity
=
None
@
property
def
flask_app
(
self
)
->
flask
.
Flask
:
return
flask
.
current_app
@
property
def
find
(
self
):
return
self
.
_rest_service
.
find
...
...
portal/service/submissions.py
View file @
6b8f2b86
...
...
@@ -202,10 +202,12 @@ class SubmissionsService(GeneralService):
def
process_submission_params
(
self
,
params
:
dict
,
project
:
Project
,
user
:
User
):
file_params
=
params
.
get
(
'file_params'
)
file_params
[
'from_dir'
]
=
params
.
get
(
'from_dir'
)
or
project
.
codename
source
=
file_params
.
get
(
'source'
)
if
source
and
source
[
'type'
]
==
'git'
:
source
[
'url'
]
=
source
.
get
(
'url'
)
or
self
.
__get_default_git_url
(
project
,
user
)
url
=
source
.
get
(
'url'
)
if
not
url
:
source
[
'url'
]
=
self
.
__get_default_git_url
(
project
,
user
)
file_params
[
'from_dir'
]
=
params
.
get
(
'from_dir'
)
or
project
.
codename
return
params
def
__get_default_git_url
(
self
,
project
:
Project
,
user
:
User
):
...
...
tests/rest/test_course.py
View file @
6b8f2b86
...
...
@@ -79,6 +79,19 @@ def test_read(client):
rest_tools
.
assert_course
(
c
,
course
)
def
test_read_course_users
(
client
):
course
=
Course
.
query
.
filter_by
(
codename
=
"testcourse2"
).
first
()
response
=
rest_tools
.
make_request
(
client
,
f
"/courses/
{
course
.
id
}
/clients"
)
assert_response
(
response
,
200
)
users
=
rest_tools
.
extract_data
(
response
)
course_users
=
set
()
for
role
in
course
.
roles
:
course_users
.
update
(
role
.
clients
)
assert
users
assert
len
(
users
)
==
4
assert
len
(
course_users
)
==
len
(
users
)
def
test_update
(
client
):
c
=
Course
.
query
.
filter_by
(
codename
=
"testcourse1"
).
first
()
request_dict
=
dict
(
...
...
tests/rest/test_project.py
View file @
6b8f2b86
...
...
@@ -3,6 +3,7 @@ from datetime import timedelta
import
pytest
from
flask_jwt_extended
import
create_access_token
from
mock
import
patch
from
portal.database.models
import
Course
,
Project
,
User
from
portal.tools.time
import
current_time
,
strip_seconds
...
...
@@ -177,6 +178,7 @@ def request_dict() -> dict:
}
@
pytest
.
mark
.
celery
(
result_backend
=
'redis://'
)
def
test_create_submission
(
client
,
request_dict
):
cpp
=
Course
.
query
.
filter_by
(
codename
=
"testcourse1"
).
first
()
p
=
cpp
.
projects
[
0
]
...
...
@@ -198,6 +200,7 @@ def test_create_submission(client, request_dict):
rest_tools
.
assert_submission_in
(
user_updated
.
submissions
,
new_submission
)
@
pytest
.
mark
.
celery
(
result_backend
=
'redis://'
)
def
test_create_submission_as_different_user
(
client
,
rest_service
,
request_dict
):
cpp
=
rest_service
.
find
.
course
(
"testcourse1"
)
proj
=
cpp
.
projects
[
0
]
...
...
@@ -217,6 +220,7 @@ def test_create_submission_as_different_user(client, rest_service, request_dict)
rest_tools
.
assert_submission_in
(
user_updated
.
submissions
,
new_submission
)
@
pytest
.
mark
.
celery
(
result_backend
=
'redis://'
)
def
test_create_submission_as_student
(
client
,
ent_mocker
,
rest_service
,
request_dict
):
user
,
course
,
project
=
ent_mocker
.
create_user_in_course
(
'testuser'
,
role_type
=
'student'
)
path
=
f
"/courses/
{
course
.
codename
}
/projects/
{
project
.
name
}
/submissions"
...
...
@@ -229,6 +233,7 @@ def test_create_submission_as_student(client, ent_mocker, rest_service, request_
assert
new_submission
[
'id'
]
@
pytest
.
mark
.
celery
(
result_backend
=
'redis://'
)
def
test_create_submission_second_should_fail
(
client
,
ent_mocker
,
rest_service
,
request_dict
):
user
,
course
,
project
=
ent_mocker
.
create_user_in_course
(
'testuser'
,
role_type
=
'student'
)
path
=
f
"/courses/
{
course
.
codename
}
/projects/
{
project
.
name
}
/submissions"
...
...
@@ -244,3 +249,36 @@ def test_create_submission_second_should_fail(client, ent_mocker, rest_service,
credentials
=
user_credentials
)
assert_response
(
response
,
code
=
429
)
@
pytest
.
fixture
()
def
defaults_dict
():
return
{
"project_params"
:
{},
"file_params"
:
{
"source"
:
{
"type"
:
"git"
,
"branch"
:
"master"
,
"checkout"
:
"master"
}
}
}
@
pytest
.
mark
.
celery
(
result_backend
=
'redis://'
)
def
test_create_submission_as_with_default_params
(
client
,
ent_mocker
,
rest_service
,
defaults_dict
):
user
,
course
,
project
=
ent_mocker
.
create_user_in_course
(
'testuser'
,
role_type
=
'student'
)
path
=
f
"/courses/
{
course
.
codename
}
/projects/
{
project
.
name
}
/submissions"
user_credentials
=
get_user_credentials
(
user
.
username
)
response
=
rest_tools
.
make_request
(
client
,
path
,
json
=
defaults_dict
,
method
=
'post'
,
credentials
=
user_credentials
)
assert_response
(
response
,
code
=
201
)
new_submission
=
rest_tools
.
extract_data
(
response
)
assert
new_submission
[
'id'
]
submission
=
rest_service
.
find
.
submission
(
new_submission
[
'id'
])
assert
submission
.
project
==
project
assert
submission
.
course
==
course
assert
submission
.
user
==
user
assert
submission
.
parameters
[
'file_params'
][
'from_dir'
]
==
project
.
codename
gitlab_url
=
f
'git@gitlab.local/
{
user
.
username
}
/
{
course
.
codename
}
'
assert
submission
.
parameters
[
'file_params'
][
'source'
][
'url'
]
==
gitlab_url
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