Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
3pia
VISPA
VISPA web
Commits
358d2f22
Commit
358d2f22
authored
Dec 20, 2016
by
Benjamin Fischer
Browse files
[usermanagment] Implemented new controller needed for API-untangling.
parent
9d4347ef
Changes
5
Hide whitespace changes
Inline
Side-by-side
vispa/controller/usermanagement.py
View file @
358d2f22
...
...
@@ -13,9 +13,216 @@ from vispa.models.workgroup import Workgroup, WorkgroupItem
import
cherrypy
import
json
from
itertools
import
izip
from
inspect
import
getargspec
from
collections
import
deque
def
DB
():
return
cherrypy
.
request
.
db
def
call_mix
(
func
,
*
args
,
**
kwargs
):
return
func
(
*
args
,
**
{
arg
:
kwargs
[
arg
]
for
arg
in
getargspec
(
func
)[
0
]
if
arg
in
kwargs
})
class
Rights
(
int
):
levels
=
[
"none"
,
"public"
,
"indirect"
,
"member"
,
"manager"
,
"admin"
,
]
def
test
(
self
,
obj
):
"""
Tests wether the object interaction is allowed with the given rights.
"""
user
=
cherrypy
.
request
.
user
fallback
=
(
lambda
:
[
user
])
if
user
==
obj
else
list
return
self
<=
(
self
.
admin
if
user
.
serveradmin
else
self
.
manager
if
getattr
(
obj
,
"get_managers"
,
fallback
)()
else
self
.
member
if
user
in
getattr
(
obj
,
"get_users"
,
fallback
)()
else
self
.
indirect
if
False
else
# TODO: implement this
self
.
public
if
getattr
(
self
,
"privacy"
,
-
1
)
==
Group
.
PUBLIC
else
self
.
none
)
@
staticmethod
def
extend
(
base
,
extension
,
delete
=
[]):
ret
=
{}
ret
.
update
(
base
)
ret
.
update
(
extension
)
for
d
in
delete
:
del
ret
[
d
]
return
ret
for
i
,
name
in
enumerate
(
Rights
.
levels
):
setattr
(
Rights
,
name
,
Rights
(
i
))
class
BaseController
(
object
):
def
__init__
(
self
,
table
,
rights
=
{},
assocs
=
[]):
self
.
_table
=
table
self
.
_rights
=
rights
for
assoc
in
assocs
:
setattr
(
self
,
assoc
.
_assoc
,
assoc
)
setattr
(
assoc
,
"_master"
,
self
)
def
_rga
(
self
,
rights
,
*
names
):
# collect the object to work on
tar
=
self
tars
=
deque
([
tar
])
for
n
in
range
(
len
(
names
)
-
1
):
tar
=
tar
.
_master
tars
.
appendleft
(
tar
)
rights
=
self
.
_rights
.
get
(
rights
,
self
.
_rights
[
"__default__"
])
if
type
(
rights
)
is
not
list
:
rights
=
[
rights
]
good
=
[
True
]
*
len
(
rights
)
objs
=
deque
()
for
tar
,
name
,
right
in
izip
(
tars
,
names
,
izip
(
*
rights
)):
obj
=
tar
.
_table
.
get_by_name
(
DB
(),
name
)
if
obj
is
None
:
# TODO: this is a info leak (about existence)
raise
AjaxException
(
404
)
good
=
[
g
and
Rights
(
r
).
test
(
obj
)
for
g
,
r
in
zip
(
good
,
right
)]
if
True
not
in
good
:
raise
AjaxException
(
403
)
objs
.
append
(
obj
)
return
objs
def
_rt
(
self
,
rights
):
rights
=
self
.
_rights
.
get
(
rights
,
self
.
_rights
[
"__default__"
])
if
type
(
rights
)
is
not
list
:
rights
=
[
rights
]
if
not
any
(
all
(
r
.
test
(
None
)
for
r
in
right
)
for
right
in
rights
):
raise
AjaxException
(
403
)
def
_rf
(
self
,
rights
,
obj_iter
):
rights
=
self
.
_rights
.
get
(
rights
,
self
.
_rights
[
"__default__"
])
rights
=
Rights
(
rights
[
0
]
if
type
(
rights
)
is
tuple
else
rights
)
if
type
(
rights
)
is
not
list
:
rights
=
[
rights
]
return
[
obj
for
obj
in
obj_iter
if
any
(
r
.
test
(
obj
)
for
r
in
rights
)]
# base tables
class
TableController
(
BaseController
):
"""
Basic controller for accessing items of a table.
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
_setters
=
kwargs
.
pop
(
"setters"
,
[])
super
(
TableController
,
self
).
__init__
(
*
args
,
**
kwargs
)
@
cherrypy
.
expose
def
create
(
self
,
name
):
self
.
_rt
(
"create"
)
self
.
_table
.
create
(
DB
(),
name
)
@
cherrypy
.
expose
def
list
(
self
):
return
[
entry
.
to_dict
()
for
entry
in
self
.
_rf
(
"list"
,
self
.
_table
.
all
(
DB
()))]
@
cherrypy
.
expose
def
info
(
self
,
name
):
base
,
=
self
.
_rga
(
"info"
,
name
)
return
base
.
to_dict
()
@
cherrypy
.
expose
def
rename
(
self
,
name
,
new_name
):
base
,
=
self
.
_rga
(
"rename"
,
name
)
base
.
rename
(
DB
(),
new_name
)
@
cherrypy
.
expose
def
delete
(
self
,
name
):
base
,
=
self
.
_rga
(
"delete"
,
name
)
base
.
delete
(
DB
())
@
cherrypy
.
expose
def
update
(
self
,
**
kwargs
):
for
key
,
value
in
kwargs
.
items
():
if
key
in
self
.
_setters
:
base
,
=
self
.
_rgs
(
"update_%s"
%
key
,
name
)
func
=
getattr
(
base
,
"set_%s"
%
key
)
func
(
value
)
else
:
raise
AjaxException
(
"Unknown property to updated: %s"
%
key
,
404
)
class
AssociationController
(
BaseController
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
_assoc
=
kwargs
.
pop
(
"assoc"
,
[])
super
(
AssociationController
,
self
).
__init__
(
*
args
,
**
kwargs
)
@
cherrypy
.
expose
def
list
(
self
,
name
):
base
,
=
self
.
_rga
(
"list"
,
name
)
func
=
getattr
(
base
,
"get_%ss"
%
self
.
_assoc
)
return
[
obj
.
to_dict
()
for
obj
in
call_mix
(
func
,
recursion_depth
=
0
)]
@
cherrypy
.
expose
def
add
(
self
,
name
,
assoc_name
):
base
,
target
=
self
.
_rga
(
"add"
,
name
,
assoc_name
)
func
=
getattr
(
base
,
"add_%s"
%
self
.
_assoc
)
func
(
DB
(),
target
)
@
cherrypy
.
expose
def
remove
(
self
,
name
,
assoc_name
):
base
,
target
=
self
.
_rga
(
"remove"
,
name
,
assoc_name
)
func
=
getattr
(
base
,
"remove_%s"
%
self
.
_assoc
)
func
(
DB
(),
target
)
class
AssociationToGroupController
(
AssociationController
):
@
cherrypy
.
expose
def
add
(
self
,
name
,
assoc_name
,
password
=
""
):
try
:
super
(
AssociationToGroupController
,
self
).
add
(
name
=
name
,
assoc_name
=
assoc_name
)
except
AjaxException
as
e
:
if
e
.
code
!=
403
:
raise
e
# now try special cases
base
,
target
=
self
.
_rga
(
"add_self"
,
name
,
assoc_name
)
func
=
getattr
(
base
,
"add_%s"
%
self
.
_assoc
)
conft
=
Group_User_Assoc
if
self
.
_table
.
__name__
==
"User"
else
Group_Group_Assoc
if
base
.
privacy
==
Group
.
PUBLIC
:
func
(
DB
(),
target
,
conft
.
CONFIRMED
)
elif
base
.
privacy
==
Group
.
PROTECTED
:
if
not
sha256_crypt
.
verify
(
password
,
base
.
password
):
raise
AjaxException
(
403
)
func
(
DB
(),
target
,
conft
.
CONFIRMED
)
elif
base
.
privacy
==
Group
.
PRIVATE
:
func
(
DB
(),
target
,
conft
.
UNCONFIRMED
)
@
cherrypy
.
expose
def
confirm
(
self
,
name
,
assoc_name
):
base
,
target
=
self
.
_rga
(
"confirm"
,
name
,
assoc_name
)
func
=
getattr
(
base
,
"confirm_%s"
%
self
.
_assoc
)
func
(
DB
(),
target
)
class
AssociationDeepController
(
AssociationController
):
@
cherrypy
.
expose
def
list
(
self
,
name
,
mid_name
):
base
,
mid
,
=
self
.
_rga
(
"list"
,
name
)
func
=
getattr
(
base
,
"get_%ss"
%
self
.
_assoc
)
return
[
obj
.
to_dict
()
for
obj
in
call_mix
(
func
,
mid
,
recursion_depth
=
0
)]
@
cherrypy
.
expose
def
add
(
self
,
name
,
mid_name
,
assoc_name
):
base
,
mid
,
target
=
self
.
_rga
(
"add"
,
name
,
assoc_name
)
func
=
getattr
(
base
,
"add_%s"
%
self
.
_assoc
)
func
(
DB
(),
mid
,
target
)
@
cherrypy
.
expose
def
remove
(
self
,
name
,
mid_name
,
assoc_name
):
base
,
mid
,
target
=
self
.
_rga
(
"remove"
,
name
,
assoc_name
)
func
=
getattr
(
base
,
"remove_%s"
%
self
.
_assoc
)
func
(
DB
(),
mid
,
target
)
class
UMAjaxController
(
AbstractController
):
"""
TODO: UPDATE THIS
The UMAjaxController inherits all methods, which are neccessery for the user management. Most
of the function names are chosen self explanantory, while the first word corresponds to the
object of interest and the rest to the action performed on the object, e.g. user_get_groups
...
...
@@ -25,6 +232,81 @@ class UMAjaxController(AbstractController):
properties.
"""
def
__init__
(
self
):
super
(
UMAjaxController
,
self
).
__init__
()
# some commonly used rights
rights_admin
=
{
"__default__"
:
(
Rights
.
admin
,)
*
3
}
rights_manager
=
{
"__default__"
:
(
Rights
.
manager
,
Rights
.
none
)}
rights_assoc
=
{
"list"
:
(
Rights
.
member
,),
"add"
:
(
Rights
.
manager
,
Rights
.
none
),
"remove"
:
[
(
Rights
.
manager
,
Rights
.
none
),
# managers can kick members
(
Rights
.
none
,
Rights
.
manager
),
# anyone can leave on their own
]
}
# now define the controllers
self
.
permission
=
TableController
(
table
=
Permission
,
rights
=
rights_admin
)
self
.
role
=
TableController
(
table
=
Role
,
rights
=
rights_admin
,
assocs
=
[
AssociationController
(
table
=
Permission
,
assoc
=
"permission"
,
rights
=
rights_admin
),
])
self
.
workgroup
=
TableController
(
table
=
Workgroup
,
rights
=
{
"list"
:
(
Rights
.
member
,),
"info"
:
(
Rights
.
member
,),
"create"
:
(
Rights
.
none
,),
"delete"
:
(
Rights
.
manager
,),
"__default__"
:
(
Rights
.
manager
,)
},
assocs
=
[
AssociationController
(
table
=
User
,
assoc
=
"manager"
,
rights
=
rights_manager
),
AssociationController
(
table
=
User
,
assoc
=
"user"
,
rights
=
rights_assoc
)
])
self
.
group
=
TableController
(
table
=
Group
,
rights
=
{
"list"
:
(
Rights
.
public
,),
"info"
:
(
Rights
.
member
,),
"create"
:
(
Rights
.
admin
,),
"delete"
:
(
Rights
.
admin
,),
"update_status"
:
(
Rights
.
admin
,),
"__default__"
:
(
Rights
.
manager
,),
},
assocs
=
[
AssociationController
(
table
=
User
,
assoc
=
"manager"
,
rights
=
rights_manager
),
]
+
[
AssociationToGroupController
(
table
=
t
,
assoc
=
a
,
rights
=
Rights
.
extend
(
rights_assoc
,
{
"list"
:
(
Rights
.
public
,),
"add"
:
(
Rights
.
manager
,
Rights
.
none
),
"add_self"
:
(
Rights
.
none
,
Rights
.
manager
),
}))
for
t
,
a
in
[
(
User
,
"user"
),
(
Group
,
"child_group"
)
]
],
setters
=
[
"privacy"
,
"status"
,
"password"
,
])
self
.
project
=
TableController
(
table
=
Project
,
rights
=
{
"list"
:
(
Rights
.
member
,),
"info"
:
(
Rights
.
member
,),
"create"
:
(
Rights
.
admin
,),
"delete"
:
(
Rights
.
admin
,),
"update_status"
:
(
Rights
.
admin
,),
"__default__"
:
(
Rights
.
manager
,),
},
assocs
=
[
AssociationController
(
table
=
User
,
assoc
=
"manager"
,
rights
=
rights_manager
),
]
+
[
AssociationController
(
table
=
t
,
assoc
=
a
,
rights
=
rights_assoc
,
assocs
=
[
AssociationDeepController
(
table
=
Role
,
assoc
=
"%s_role"
%
a
,
rights
=
rights_admin
)
])
for
t
,
a
in
[
(
User
,
"user"
),
(
Group
,
"group"
)
]
],
setters
=
[
"status"
])
@
cherrypy
.
expose
def
user_get_groups
(
self
):
"""
...
...
vispa/models/group.py
View file @
358d2f22
...
...
@@ -84,6 +84,16 @@ class Group(Base):
primaryjoin
=
id
==
Group_Group_Assoc
.
parent_group_id
,
backref
=
"parent_group"
)
def
to_dict
(
self
):
return
{
"id"
:
self
.
id
,
"name"
:
self
.
name
,
"created"
:
self
.
created
.
isoformat
(),
"privacy"
:
self
.
privacy
,
"password"
:
not
not
self
.
password
,
# don't show this
"status"
:
self
.
status
,
}
@
staticmethod
def
get_by_name
(
session
,
name
):
"""
...
...
@@ -165,7 +175,7 @@ class Group(Base):
"""
return
session
.
query
(
Group
)
def
delete
(
self
):
def
delete
(
self
,
session
=
None
):
"""
Delete group. Internally, the delete flag is set, its not deleted from the database.
"""
...
...
vispa/models/project.py
View file @
358d2f22
...
...
@@ -106,6 +106,16 @@ class Project(Base):
groups
=
relationship
(
"Project_Group_Assoc"
,
backref
=
"project"
)
items
=
relationship
(
"ProjectItem"
,
backref
=
"project"
)
def
to_dict
(
self
):
return
{
"id"
:
self
.
id
,
"name"
:
self
.
name
,
"created"
:
self
.
created
.
isoformat
(),
"status"
:
self
.
status
,
"password"
:
not
not
self
.
password
,
# don't show this
"status"
:
self
.
status
,
}
@
staticmethod
def
get_by_id
(
session
,
gid
):
"""
...
...
@@ -172,7 +182,7 @@ class Project(Base):
if
name
is
None
:
raise
Exception
(
"Invalid projectname"
)
if
Project
.
get_by_name
(
session
,
name
)
is
not
None
:
raise
Exception
(
"Project %s already exists"
%
name
)
raise
Exception
(
"Project %s already exists"
%
name
)
# name valid -> create project
session
.
add
(
Project
(
name
=
name
))
session
.
commit
()
...
...
@@ -228,7 +238,7 @@ class Project(Base):
def
get_users
(
self
):
"""
Returns users of project.
Returns users of project.
:returns: list of Project_User_Assoc objects
"""
...
...
@@ -250,7 +260,7 @@ class Project(Base):
assoc
=
session
.
query
(
Project_User_Assoc
).
filter_by
(
user_id
=
user
.
id
)
\
.
filter_by
(
project_id
=
self
.
id
).
first
()
if
assoc
is
not
None
:
raise
Exception
(
"User %s already in project %s"
%
(
user
.
name
,
self
.
name
))
raise
Exception
(
"User %s already in project %s"
%
(
user
.
name
,
self
.
name
))
assoc
=
Project_User_Assoc
(
project_id
=
self
.
id
,
user_id
=
user
.
id
)
assoc
.
user
=
user
self
.
users
.
append
(
assoc
)
...
...
@@ -273,7 +283,7 @@ class Project(Base):
assoc
=
session
.
query
(
Project_User_Assoc
).
filter_by
(
user_id
=
user
.
id
)
\
.
filter_by
(
project_id
=
self
.
id
).
first
()
if
assoc
is
None
:
raise
Exception
(
"User %s not in project %s"
%
(
user
.
name
,
self
.
name
))
raise
Exception
(
"User %s not in project %s"
%
(
user
.
name
,
self
.
name
))
session
.
delete
(
assoc
)
def
get_groups
(
self
):
...
...
@@ -313,7 +323,7 @@ class Project(Base):
assoc
=
session
.
query
(
Project_Group_Assoc
).
filter_by
(
group_id
=
group
.
id
)
\
.
filter_by
(
project_id
=
self
.
id
).
first
()
if
assoc
is
not
None
:
raise
Exception
(
"Group %s already in project %s"
%
(
group
.
name
,
self
.
name
))
raise
Exception
(
"Group %s already in project %s"
%
(
group
.
name
,
self
.
name
))
assoc
=
Project_Group_Assoc
(
project_id
=
self
.
id
,
group_id
=
group
.
id
)
assoc
.
group
=
group
self
.
groups
.
append
(
assoc
)
...
...
@@ -330,13 +340,13 @@ class Project(Base):
:raises: TypeError if group is not instance of Group
:raises: Exception if group is not in project
"""
if
not
isinstance
(
group
.
vispa
.
models
.
group
.
Group
):
if
not
isinstance
(
group
,
vispa
.
models
.
group
.
Group
):
raise
TypeError
(
'invalid type of group'
)
# get Project_Group_Assoc object
assoc
=
session
.
query
(
Project_Group_Assoc
).
filter_by
(
group_id
=
group
.
id
)
\
.
filter_by
(
project_id
=
self
.
id
).
first
()
if
assoc
is
None
:
raise
Exception
(
"Group %s not in project %s"
%
(
group
.
name
,
self
.
name
))
raise
Exception
(
"Group %s not in project %s"
%
(
group
.
name
,
self
.
name
))
session
.
delete
(
assoc
)
def
get_managers
(
self
):
...
...
@@ -372,7 +382,7 @@ class Project(Base):
raise
TypeError
(
'invalid type of manager'
)
# is given manager manager of project?
if
manager
not
in
self
.
managers
:
raise
Exception
(
"User %s is not manager of project %s"
%
(
manager
.
name
,
self
.
name
))
raise
Exception
(
"User %s is not manager of project %s"
%
(
manager
.
name
,
self
.
name
))
self
.
managers
.
remove
(
manager
)
def
get_roles_of_user
(
self
,
user
):
...
...
@@ -393,7 +403,7 @@ class Project(Base):
if
x
.
user_id
==
user
.
id
:
assoc
=
x
if
assoc
is
None
:
raise
Exception
(
"User %s not in project %s"
%
(
user
.
name
,
self
.
name
))
raise
Exception
(
"User %s not in project %s"
%
(
user
.
name
,
self
.
name
))
return
assoc
.
roles
def
get_roles_of_group
(
self
,
group
):
...
...
@@ -414,7 +424,7 @@ class Project(Base):
if
x
.
group_id
==
group
.
id
:
assoc
=
x
if
assoc
is
None
:
raise
Exception
(
"Group %s not in project %s"
%
(
group
.
name
,
self
.
name
))
raise
Exception
(
"Group %s not in project %s"
%
(
group
.
name
,
self
.
name
))
return
assoc
.
roles
def
set_roles_of_user
(
self
,
user
,
roles
):
...
...
@@ -440,7 +450,7 @@ class Project(Base):
if
x
.
user_id
==
user
.
id
:
assoc
=
x
if
assoc
is
None
:
raise
Exception
(
"User %s not in project %s"
%
(
user
.
name
,
self
.
name
))
raise
Exception
(
"User %s not in project %s"
%
(
user
.
name
,
self
.
name
))
assoc
.
roles
=
roles
def
add_roles_to_user
(
self
,
user
,
roles
):
...
...
@@ -466,9 +476,63 @@ class Project(Base):
if
x
.
user_id
==
user
.
id
:
assoc
=
x
if
assoc
is
None
:
raise
Exception
(
"User %s not in project %s"
%
(
user
.
name
,
self
.
name
))
raise
Exception
(
"User %s not in project %s"
%
(
user
.
name
,
self
.
name
))
assoc
.
roles
.
extend
(
roles
)
def
get_user_roles
(
self
,
user
):
return
self
.
get_roles_of_user
(
user
=
user
)
def
add_user_role
(
self
,
user
,
role
):
if
not
isinstance
(
user
,
User
):
raise
TypeError
(
'invalid type of user'
)
if
not
isinstance
(
role
,
Role
):
raise
TypeError
(
'Invalid type of roles'
)
for
assoc
in
self
.
users
:
if
assoc
.
user_id
==
user
.
id
:
if
role
in
assoc
.
roles
:
raise
Exception
(
"User %s has role %s already"
%
(
user
.
name
,
role
.
name
))
assoc
.
roles
.
append
(
role
)
else
:
raise
Exception
(
"User %s not in project %s"
%
(
user
.
name
,
self
.
name
))
def
remove_user_role
(
self
,
user
,
role
):
if
not
isinstance
(
user
,
User
):
raise
TypeError
(
'invalid type of user'
)
if
not
isinstance
(
role
,
Role
):
raise
TypeError
(
'Invalid type of roles'
)
for
assoc
in
self
.
users
:
if
assoc
.
user_id
==
user
.
id
:
assoc
.
roles
.
remove
(
role
)
else
:
raise
Exception
(
"User %s not in project %s"
%
(
user
.
name
,
self
.
name
))
def
get_group_roles
(
self
,
group
):
return
self
.
get_roles_of_group
(
group
=
group
)
def
add_group_role
(
self
,
group
,
role
):
if
not
isinstance
(
group
,
vispa
.
models
.
group
.
Group
):
raise
TypeError
(
'invalid type of group'
)
if
not
isinstance
(
role
,
Role
):
raise
TypeError
(
'Invalid type of roles'
)
for
assoc
in
self
.
groups
:
if
assoc
.
group_id
==
group
.
id
:
if
role
in
assoc
.
roles
:
raise
Exception
(
"Group %s has role %s already"
%
(
group
.
name
,
role
.
name
))
assoc
.
roles
.
append
(
role
)
else
:
raise
Exception
(
"Group %s not in project %s"
%
(
group
.
name
,
self
.
name
))
def
remove_group_role
(
self
,
group
,
role
):
if
not
isinstance
(
group
,
vispa
.
models
.
group
.
Group
):
raise
TypeError
(
'invalid type of group'
)
if
not
isinstance
(
role
,
Role
):
raise
TypeError
(
'Invalid type of roles'
)
for
assoc
in
self
.
groups
:
if
assoc
.
group_id
==
group
.
id
:
assoc
.
roles
.
remove
(
role
)
else
:
raise
Exception
(
"Group %s not in project %s"
%
(
group
.
name
,
self
.
name
))
def
set_roles_of_group
(
self
,
group
,
roles
):
"""
Sets the roles of a group in a project.
...
...
@@ -492,7 +556,7 @@ class Project(Base):
if
x
.
group_id
==
group
.
id
:
assoc
=
x
if
assoc
is
None
:
raise
Exception
(
"Group %s not in project %s"
%
(
group
.
name
,
self
.
name
))
raise
Exception
(
"Group %s not in project %s"
%
(
group
.
name
,
self
.
name
))
assoc
.
roles
=
roles
def
add_roles_to_group
(
self
,
group
,
roles
):
...
...
@@ -518,7 +582,7 @@ class Project(Base):
if
x
.
group_id
==
group
.
id
:
assoc
=
x
if
assoc
is
None
:
raise
Exception
(
"Group %s not in project %s"
%
(
group
.
name
,
self
.
name
))
raise
Exception
(
"Group %s not in project %s"
%
(
group
.
name
,
self
.
name
))
assoc
.
roles
.
extend
(
roles
)
def
get_items
(
self
,
itemtype
=
None
):
...
...
vispa/models/role.py
View file @
358d2f22
...
...
@@ -25,6 +25,13 @@ class Permission(Base):
name
=
Column
(
Unicode
(
255
),
nullable
=
False
,
unique
=
True
)
created
=
Column
(
DateTime
,
nullable
=
False
,
default
=
datetime
.
now
)
def
to_dict
(
self
):
return
{
"id"
:
self
.
id
,
"name"
:
self
.
name
,
"created"
:
self
.
created
.
isoformat
()
}
@
staticmethod
def
get_by_id
(
session
,
gid
):
"""
...
...
@@ -145,6 +152,13 @@ class Role(Base):
created
=
Column
(
DateTime
,
nullable
=
False
,
default
=
datetime
.
now
)
permissions
=
relationship
(
"Permission"
,
secondary
=
role_permission_association
)
def
to_dict
(
self
):
return
{
"id"
:
self
.
id
,
"name"
:
self
.
name
,
"created"
:
self
.
created
.
isoformat
(),
}
@
staticmethod
def
get_by_id
(
session
,
gid
):
"""
...
...
@@ -285,3 +299,16 @@ class Role(Base):
if
not
isinstance
(
permission
,
Permission
):
raise
TypeError
(
'Invalid type of permission'
)
self
.
permissions
=
permissions
def
get_permissions
(
self
):
return
self
.
permissions
def
add_permission
(
self
,
permission
):
self
.
add_permissions
([
permission
])
def
remove_permssion
(
self
,
permission
):
if
not
isinstance
(
permission
,
Permission
):
raise
TypeError
(
'Invalid type of permission'
)
if
permission
not
in
self
.
permissions
:
raise
Exception
(
'Permission %s not in role %s'
%
(
permission
.
name
,
self
.
name
))
self
.
permission
.
remove
(
permission
)
vispa/models/workgroup.py
View file @
358d2f22
...
...
@@ -35,6 +35,13 @@ class Workgroup(Base):
users
=
relationship
(
"User"
,
secondary
=
workgroup_user_association
,
backref
=
"workgroups"
)
items
=
relationship
(
"WorkgroupItem"
,
backref
=
"workgroup"
)
def
to_dict
(
self
):
return
{
"id"
:
self
.
id
,
"name"
:
self
.
name
,
"created"
:
self
.
created
.
isoformat
(),
}
@
staticmethod
def
get_by_id
(
session
,
gid
):
"""
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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