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
6aa72543
Unverified
Commit
6aa72543
authored
Sep 04, 2018
by
Peter Stanko
Browse files
Group service
parent
5e847e32
Changes
5
Hide whitespace changes
Inline
Side-by-side
portal/rest/groups.py
View file @
6aa72543
...
...
@@ -6,11 +6,8 @@ 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.service
import
auth
,
general
,
permissions
from
portal.service.groups
import
add_project_to_group
,
add_single_user_to_group
,
create_group
,
\
delete_group
,
find_projects_in_group
,
find_users_in_group_by_role
,
import_group
,
list_groups
,
\
remove_project_from_group
,
remove_single_user_from_group
,
update_group
,
\
update_user_group_membership
from
portal.service
import
general
,
permissions
from
portal.service.groups
import
GroupService
groups_namespace
=
Namespace
(
''
)
...
...
@@ -24,10 +21,9 @@ class GroupsList(Resource):
@
jwt_required
# @groups_namespace.response(200, 'List of all groups', model=groups_schema)
def
get
(
self
,
cid
:
str
):
client
=
auth
.
find_client
()
course
=
general
.
find_course
(
cid
)
return
groups_schema
.
dump
(
list_
groups
(
course
,
client
=
client
))
groups
=
GroupService
().
list_groups
(
course
)
return
groups_schema
.
dump
(
groups
)[
0
]
@
jwt_required
# @groups_namespace.response(201, 'Group created', model=group_schema)
...
...
@@ -41,7 +37,7 @@ class GroupsList(Resource):
group_schema
,
action
=
'create'
,
resource
=
'group'
)
new_group
=
create_group
(
course
,
**
data
)
new_group
=
GroupService
().
create_group
(
course
,
**
data
)
return
group_schema
.
dump
(
new_group
)[
0
],
201
...
...
@@ -71,7 +67,7 @@ class GroupResource(Resource):
permissions
.
PermissionsService
(
course
=
course
).
require
.
update_course
()
group
=
general
.
find_group
(
course
,
gid
)
delete_group
(
group
)
GroupService
(
group
).
delete_group
()
return
''
,
204
@
jwt_required
...
...
@@ -87,7 +83,7 @@ class GroupResource(Resource):
)
group
=
general
.
find_group
(
course
,
gid
)
update_group
(
group
,
data
)
GroupService
(
group
).
update_group
(
data
)
return
''
,
204
...
...
@@ -106,7 +102,7 @@ class GroupUsersList(Resource):
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
belongs_to_group
(
group
)
users
=
find_users_
in_group_
by_role
(
course
,
group
,
role_id
)
users
=
GroupService
(
group
).
find_users_by_role
(
course
,
role_id
)
return
users_schema
.
dump
(
users
)
@
jwt_required
...
...
@@ -124,7 +120,7 @@ class GroupUsersList(Resource):
group
=
general
.
find_group
(
course
,
gid
)
# everything from users_add is added, THEN everything from users_remove
# is removed
update_user_group
_membership
(
group
,
data
)
GroupService
(
group
).
update
_membership
(
data
)
return
''
,
204
...
...
@@ -148,7 +144,7 @@ class GroupAddOrDeleteSingleUser(Resource):
group
=
general
.
find_group
(
course
,
gid
)
user
=
general
.
find_user
(
uid
)
add_single_user_to_group
(
group
,
user
)
GroupService
(
group
).
add_user
(
user
)
return
''
,
204
@
jwt_required
...
...
@@ -161,7 +157,7 @@ class GroupAddOrDeleteSingleUser(Resource):
group
=
general
.
find_group
(
course
,
gid
)
user
=
general
.
find_user
(
uid
)
remove_single_user_from_group
(
group
,
user
)
GroupService
(
group
).
remove_user
(
user
)
return
''
,
204
...
...
@@ -178,7 +174,7 @@ class GroupProjectsList(Resource):
# authorization
permissions
.
PermissionsService
(
course
=
course
).
require
.
belongs_to_group
(
group
)
projects
=
find_projects_in_group
(
group
)
projects
=
GroupService
(
group
).
find_projects
(
)
return
projects_schema
.
dump
(
projects
)
...
...
@@ -202,7 +198,7 @@ class GroupAddOrDeleteProject(Resource):
group
=
general
.
find_group
(
course
,
gid
)
project
=
general
.
find_project
(
course
,
pid
)
add_project_to_group
(
group
,
project
)
GroupService
(
group
).
add_project
(
project
)
return
''
,
204
@
jwt_required
...
...
@@ -217,7 +213,7 @@ class GroupAddOrDeleteProject(Resource):
group
=
general
.
find_group
(
course
,
gid
)
project
=
general
.
find_project
(
course
,
pid
)
remove_project_from_group
(
group
,
project
)
GroupService
(
group
).
remove_project
(
project
)
return
''
,
204
...
...
@@ -236,5 +232,5 @@ class GroupImport(Resource):
data
=
rest_helpers
.
parse_request_data
(
group_import_schema
,
action
=
'import'
,
resource
=
'group'
)
new_group
=
import_group
(
data
,
target_course
)
new_group
=
GroupService
().
import_group
(
data
,
target_course
)
return
group_schema
.
dump
(
new_group
),
201
portal/rest/roles.py
View file @
6aa72543
...
...
@@ -7,10 +7,8 @@ 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.service
import
auth
,
general
,
permissions
from
portal.service.roles
import
add_single_client_to_role
,
create_role
,
delete_role
,
list_roles
,
\
remove_single_client_from_role
,
update_clients_membership_in_role
,
update_role
,
\
update_role_permissions
from
portal.service
import
general
,
permissions
from
portal.service.roles
import
RoleService
roles_namespace
=
Namespace
(
''
)
...
...
@@ -23,9 +21,9 @@ class RoleList(Resource):
@
jwt_required
# @roles_namespace.response(200, 'Roles list', model=roles_schema)
def
get
(
self
,
cid
):
client
=
auth
.
find_client
()
course
=
general
.
find_course
(
cid
)
return
roles_schema
.
dump
(
list_roles
(
course
,
client
))
roles
=
RoleService
().
list_roles
(
course
)
return
roles_schema
.
dump
(
roles
)[
0
]
@
jwt_required
# @roles_namespace.response(201, 'Role created', model=role_schema)
...
...
@@ -37,7 +35,7 @@ class RoleList(Resource):
data
=
rest_helpers
.
parse_request_data
(
role_schema
,
action
=
'create'
,
resource
=
'role'
)
new_role
=
create_role
(
course
,
**
data
)
new_role
=
RoleService
().
create_role
(
course
,
**
data
)
return
role_schema
.
dump
(
new_role
)[
0
],
201
...
...
@@ -65,7 +63,7 @@ class RoleResource(Resource):
permissions
.
PermissionsService
(
course
=
course
).
require
.
update_course
()
role
=
general
.
find_role
(
course
,
rid
)
delete_role
(
role
)
RoleService
(
role
).
delete_role
()
return
''
,
204
@
jwt_required
...
...
@@ -80,7 +78,7 @@ class RoleResource(Resource):
)
role
=
general
.
find_role
(
course
,
rid
)
update_role
(
role
,
data
)
RoleService
(
role
).
update_role
(
data
)
return
''
,
204
...
...
@@ -114,7 +112,7 @@ class RolePermissions(Resource):
)
role
=
general
.
find_role
(
course
,
rid
)
update_
role_
permissions
(
role
,
data
)
RoleService
(
role
).
update_permissions
(
data
)
return
permissions_schema
.
dump
(
role
.
permissions
),
204
...
...
@@ -151,7 +149,7 @@ class RoleUsersList(Resource):
# everything from users_add is added, THEN everything from users_remove
# is subtracted
role
=
general
.
find_role
(
course
,
rid
)
update_clients_membership
_in_role
(
role
,
data
)
RoleService
(
role
).
update_clients_membership
(
data
)
return
''
,
204
...
...
@@ -174,7 +172,7 @@ class RoleUser(Resource):
role
=
general
.
find_role
(
course
,
rid
)
client
=
general
.
find_client
(
clid
)
add_single_client_to_role
(
role
,
client
)
RoleService
(
role
).
add_client
(
client
)
return
''
,
204
@
jwt_required
...
...
@@ -183,6 +181,6 @@ class RoleUser(Resource):
course
=
general
.
find_course
(
cid
)
permissions
.
PermissionsService
(
course
=
course
).
require
.
write_roles
()
role
=
general
.
find_role
(
course
,
rid
)
user
=
general
.
find_client
(
clid
)
remove_single_client_from_role
(
role
,
user
)
client
=
general
.
find_client
(
clid
)
RoleService
(
role
).
remove_client
(
client
)
return
''
,
204
portal/service/courses.py
View file @
6aa72543
...
...
@@ -7,9 +7,9 @@ from typing import List
from
portal
import
logger
from
portal.database.models
import
Course
,
Group
,
Role
,
User
from
portal.service
import
general
from
portal.service.groups
import
copy_group
from
portal.service.projects
import
copy_project
from
portal.service.roles
import
copy_rol
e
from
portal.service.groups
import
GroupService
from
portal.service.projects
import
ProjectService
from
portal.service.roles
import
RoleServic
e
log
=
logger
.
get_logger
(
__name__
)
...
...
@@ -53,13 +53,13 @@ class CourseService:
"""
if
config
.
get
(
'roles'
):
for
role
in
self
.
course
.
roles
:
copy_role
(
role
,
target
,
with_clients
=
config
[
'roles'
])
RoleService
(
role
).
copy_role
(
target
,
with_clients
=
config
[
'roles'
])
if
config
.
get
(
'groups'
):
for
group
in
self
.
course
.
groups
:
copy_group
(
group
,
target
,
with_users
=
config
[
'groups'
])
GroupService
(
group
).
copy_
group
(
target
,
with_users
=
config
[
'groups'
])
if
config
.
get
(
'projects'
):
for
project
in
self
.
course
.
projects
:
copy_project
(
project
,
target
)
ProjectService
(
project
).
copy_
project
(
target
)
general
.
write_entity
(
target
)
log
.
info
(
f
"[IMPORT] From
{
self
.
course
.
id
}
to:
{
target
.
id
}
."
)
...
...
portal/service/groups.py
View file @
6aa72543
...
...
@@ -3,7 +3,7 @@ Groups service
"""
import
logging
from
typing
import
List
,
Union
from
typing
import
List
from
portal.database.models
import
Course
,
Group
,
Project
,
User
from
portal.service
import
filters
,
general
,
permissions
...
...
@@ -14,241 +14,226 @@ from portal.service.users import UserService
log
=
logging
.
getLogger
(
__name__
)
def
copy_group
(
source
:
Group
,
target
:
Course
,
with_users
:
str
):
"""Copies group to a specified course
Args:
source(Group): Source group instance
target(Course): Target course instance
with_users(str): Whether it should copy with users
Returns: the new group
"""
log
.
info
(
f
"[COPY] Group:
{
source
.
id
}
to course
{
target
.
id
}
with config:
{
with_users
}
"
)
new_name
=
get_new_name
(
source
,
target
)
new_group
=
Group
(
target
,
codename
=
new_name
)
new_group
.
description
=
source
.
description
new_group
.
name
=
source
.
name
if
with_users
==
"with_users"
:
for
user
in
source
.
users
:
user
.
groups
.
append
(
new_group
)
return
new_group
def
_set_group_data
(
group
:
Group
,
data
:
dict
)
->
Group
:
return
general
.
update_entity
(
group
,
data
,
allowed
=
[
'name'
,
'description'
,
'codename'
])
def
delete_group
(
group
:
Group
):
"""Deletes group
Args:
group(Group): Group instance
"""
log
.
info
(
f
"[DELETE] Group
{
group
.
id
}
(
{
group
.
codename
}
)"
)
general
.
delete_entity
(
group
)
class
GroupService
:
def
__init__
(
self
,
group
:
Group
=
None
):
self
.
_group
=
group
@
property
def
group
(
self
)
->
Group
:
return
self
.
_group
def
__set_group_data
(
group
:
Group
,
data
:
dict
)
->
Group
:
return
general
.
update_entity
(
group
,
data
,
allowed
=
[
'name'
,
'description'
,
'codename'
])
def
copy_group
(
self
,
target
:
Course
,
with_users
:
str
)
:
"""Copies group to a specified course
Args:
target(Course): Target course instance
with_users(str): Whether it should copy with users
def
update_group
(
group
:
Group
,
data
:
dict
)
->
Group
:
"""Updates group
Args:
group(Group): Group instance
data(dict): Group data
Returns(Group): Updated group instance
"""
log
.
info
(
f
"[UPDATE] Group
{
group
.
codename
}
to
{
group
}
."
)
return
__set_group_data
(
group
,
data
)
def
create_group
(
course
:
Course
,
**
data
)
->
Course
:
"""Creates a new group
Args:
course(Course): Course instance
Keyword Args:
name(str): Name of the group
description(str): Description of the group
codename(str): Codename of the group
Returns(Group): Created group instance
"""
new_group
=
Group
(
course
=
course
)
__set_group_data
(
new_group
,
data
)
log
.
info
(
f
"[CREATE] Group for course
{
course
.
id
}
(
{
course
.
codename
}
):
{
new_group
}
"
)
return
new_group
def
update_user_group_membership
(
group
:
Group
,
data
:
dict
):
"""Updates the list of members of the group
Args:
group(Group): Group instance
data(dict): Data
"""
users_old
=
set
(
group
.
users
)
users_add
=
data
.
get
(
'add'
)
users_remove
=
data
.
get
(
'remove'
)
users
=
set
()
if
users_add
:
to_add
=
UserService
().
find_users
(
users_add
)
users
=
users_old
.
union
(
to_add
)
if
users_remove
:
to_remove
=
UserService
().
find_users
(
users_remove
)
users
=
users_old
.
difference
(
to_remove
)
group
.
users
=
list
(
users
)
general
.
write_entity
(
group
)
log
.
info
(
f
"[UPDATE] Users of group
{
group
.
codename
}
to
{
group
.
users
}
."
)
def
find_users_in_group_by_role
(
course
:
Course
,
group
:
Group
,
role_id
=
None
)
->
List
[
User
]:
"""Finds users in the group by role
Args:
course(Course): Course instance
group(Group): Group instance
role_id(str): Group id
Returns(list[User]): List of the users
"""
role
=
find_role
(
course
,
role_id
)
if
role_id
else
None
return
group
.
get_users_based_on_role
(
role
=
role
)
def
add_single_user_to_group
(
group
:
Group
,
user
:
User
)
->
Group
:
"""Adds a single user to the group
Args:
group(Group): Group instance
user(User): User instance
Returns(Group): updated group instance
"""
course
=
group
.
course
if
user
not
in
group
.
users
:
group
.
users
.
append
(
user
)
general
.
write_entity
(
group
)
Returns: the new group
"""
source
=
self
.
group
log
.
info
(
f
"[COPY] Group:
{
source
.
id
}
to course
{
target
.
id
}
with config:
{
with_users
}
"
)
new_name
=
get_new_name
(
source
,
target
)
new_group
=
Group
(
target
,
codename
=
new_name
)
new_group
.
description
=
source
.
description
new_group
.
name
=
source
.
name
if
with_users
==
"with_users"
:
for
user
in
source
.
users
:
user
.
groups
.
append
(
new_group
)
return
new_group
def
delete_group
(
self
):
"""Deletes group
"""
log
.
info
(
f
"[DELETE] Group
{
self
.
group
.
id
}
(
{
self
.
group
.
codename
}
)"
)
general
.
delete_entity
(
self
.
group
)
def
update_group
(
self
,
data
:
dict
)
->
Group
:
"""Updates group
Args:
data(dict): Group data
Returns(Group): Updated group instance
"""
log
.
info
(
f
"[UPDATE] Group
{
self
.
group
.
codename
}
to
{
group
}
."
)
return
_set_group_data
(
self
.
group
,
data
)
def
create_group
(
self
,
course
:
Course
,
**
data
)
->
Course
:
"""Creates a new group
Args:
course(Course): Course instance
Keyword Args:
name(str): Name of the group
description(str): Description of the group
codename(str): Codename of the group
Returns(Group): Created group instance
"""
new_group
=
Group
(
course
=
course
)
self
.
_group
=
new_group
_set_group_data
(
new_group
,
data
)
log
.
info
(
f
"[ADD] Added user
{
user
.
username
}
to group
{
group
.
codename
}
"
f
"in course
{
course
.
codename
}
."
)
else
:
log
.
info
(
f
"[ADD] User
{
user
.
username
}
is already in group
{
group
.
codename
}
"
f
"in course
{
course
.
codename
}
: no change."
)
return
group
def
remove_single_user_from_group
(
group
:
Group
,
user
:
User
)
->
Group
:
"""Removes single user from the group
Args:
group(Group): Group instance
user(User): User instance
Returns(Group): updated group instance
"""
course
=
group
.
course
try
:
group
.
users
.
remove
(
user
)
general
.
write_entity
(
group
)
except
ValueError
:
message
=
f
"[REMOVE] Could not remove user "
\
f
"
{
user
.
username
}
from group
{
group
.
codename
}
in course "
\
f
"
{
course
.
codename
}
: group does not contain user."
raise
PortalAPIError
(
400
,
message
=
message
)
log
.
info
(
f
"[REMOVE] User
{
user
.
username
}
from group
{
group
.
codename
}
"
f
" in course
{
course
.
codename
}
."
)
return
group
def
import_group
(
data
:
dict
,
course
:
Course
)
->
Group
:
"""Imports Group from a course
Args:
data(dict): import configuration
course(Course): Course instance
"""
source_course
=
find_course
(
data
[
'source_course'
])
source_group
=
find_group
(
source_course
,
data
[
'source_group'
])
new_group
=
copy_group
(
source_group
,
course
,
data
[
'with_users'
])
general
.
write_entity
(
new_group
)
log
.
info
(
f
"[IMPORT] Group
{
source_group
.
name
}
from course "
f
"
{
source_course
.
codename
}
to course
{
course
.
codename
}
"
f
"as
{
new_group
.
codename
}
."
)
return
new_group
def
list_groups
(
course
:
Course
,
client
:
Union
[
User
,
Course
])
->
List
[
Group
]:
"""List all groups
Args:
course(Course): Course instance
client: Client instance
Returns(list): List of all groups
"""
perm_service
=
permissions
.
PermissionsService
(
course
=
course
,
client
=
client
)
if
perm_service
.
check
.
client
([
'view_course_full'
]):
return
course
.
groups
elif
perm_service
.
check
.
client
([
'view_course_limited'
]):
return
filters
.
filter_groups_from_course
(
course
=
course
,
user
=
client
)
raise
ForbiddenError
(
uid
=
client
.
id
)
def
remove_project_from_group
(
group
:
Group
,
project
:
Project
)
->
Group
:
"""Removes projects from the group
Args:
group(Group): Group instance
project(Project): Project instance
Returns:
"""
course
=
group
.
course
try
:
group
.
projects
.
remove
(
project
)
general
.
write_entity
(
group
)
except
ValueError
:
message
=
f
"[REMOVE] Could not remove project "
\
f
"
{
project
.
codename
}
from group
{
group
.
codename
}
in course "
\
f
"
{
course
.
codename
}
: group does not contain project."
raise
PortalAPIError
(
400
,
message
=
message
)
log
.
info
(
f
"[REMOVE] Project
{
project
.
codename
}
from group
{
group
.
codename
}
"
f
" in course
{
course
.
codename
}
."
)
return
group
def
add_project_to_group
(
group
:
Group
,
project
:
Project
)
->
Group
:
"""Adds project to the group
Args:
group(Group): Group instance
project(Project): Project instance
Returns:
"""
course
=
group
.
course
if
project
not
in
group
.
projects
:
group
.
projects
.
append
(
project
)
general
.
write_entity
(
group
)
f
"[CREATE] Group for course
{
course
.
id
}
(
{
course
.
codename
}
):
{
new_group
}
"
)
return
new_group
def
update_membership
(
self
,
data
:
dict
):
"""Updates the list of members of the group
Args:
data(dict): Data
"""
users_old
=
set
(
self
.
group
.
users
)
users_add
=
data
.
get
(
'add'
)
users_remove
=
data
.
get
(
'remove'
)
users
=
set
()
if
users_add
:
to_add
=
UserService
().
find_users
(
users_add
)
users
=
users_old
.
union
(
to_add
)
if
users_remove
:
to_remove
=
UserService
().
find_users
(
users_remove
)
users
=
users_old
.
difference
(
to_remove
)
self
.
group
.
users
=
list
(
users
)
general
.
write_entity
(
self
.
group
)
log
.
info
(
f
"[UPDATE] Users of group
{
self
.
group
.
codename
}
to
{
self
.
group
.
users
}
."
)
def
find_users_by_role
(
self
,
course
:
Course
,
role_id
=
None
)
->
List
[
User
]:
"""Finds users in the group by role
Args:
course(Course): Course instance
role_id(str): Group id
Returns(list[User]): List of the users
"""
course
=
course
or
self
.
group
.
course
role
=
find_role
(
course
,
role_id
)
if
role_id
else
None
return
self
.
group
.
get_users_based_on_role
(
role
=
role
)
def
add_user
(
self
,
user
:
User
)
->
Group
:
"""Adds a single user to the group
Args:
user(User): User instance
Returns(Group): updated group instance
"""
# TODO: Check that user belongs to Course using the Role relationship
course
=
self
.
group
.
course
if
user
not
in
self
.
group
.
users
:
self
.
group
.
users
.
append
(
user
)
general
.
write_entity
(
self
.
group
)
log
.
info
(
f
"[ADD] Added user
{
user
.
username
}
to group
{
self
.
group
.
codename
}
"
f
"in course
{
course
.
codename
}
."
)
else
:
log
.
info
(
f
"[ADD] User
{
user
.
username
}
is already in group
{
self
.
group
.
codename
}
"
f
"in course
{
course
.
codename
}
: no change."
)
return
self
.
group
def
remove_user
(
self
,
user
:
User
)
->
Group
:
"""Removes single user from the group
Args:
user(User): User instance
Returns(Group): updated group instance
"""
course
=
self
.
group
.
course
try
:
self
.
group
.
users
.
remove
(
user
)
general
.
write_entity
(
self
.
group
)
except
ValueError
:
message
=
f
"[REMOVE] Could not remove user "
\
f
"
{
user
.
username
}
from group
{
self
.
group
.
codename
}
in course "
\
f
"
{
course
.
codename
}
: group does not contain user."
raise
PortalAPIError
(
400
,
message
=
message
)
log
.
info
(
f
"[REMOVE] User
{
user
.
username
}
from group
{
self
.
group
.
codename
}
"
f
" in course
{
course
.
codename
}
."
)
return
self
.
group
def
import_group
(
self
,
data
:
dict
,
course
:
Course
=
None
)
->
Group
:
"""Imports Group from a course
Args:
data(dict): import configuration