Page Menu
Home
Search
Configure Global Search
Log In
Files
F13259834
auth.py
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
3 KB
Subscribers
None
auth.py
View Options
import
enum
import
flask
import
attr
import
bson
from
pillar
import
attrs_extra
# Having any of these methods on a project means you can use Attract.
# Prerequisite: the project is set up for Attract and has a Manager assigned to it.
PROJECT_METHODS_TO_USE_ATTRACT
=
{
'PUT'
}
class
Actions
(
enum
.
Enum
):
VIEW
=
'view'
USE
=
'use'
# Required capability for a given action.
req_cap
=
{
Actions
.
VIEW
:
'attract-view'
,
Actions
.
USE
:
'attract-use'
,
}
@attr.s
class
Auth
(
object
):
"""Handles authorization for Attract."""
_log
=
attrs_extra
.
log
(
'
%s
.Auth'
%
__name__
)
Actions
=
Actions
# this allows using current_attract.auth.Actions
def
current_user_is_attract_user
(
self
)
->
bool
:
"""Returns True iff the current user has Attract User role."""
from
pillar.auth
import
current_user
return
current_user
.
has_cap
(
'attract-use'
)
def
user_is_attract_user
(
self
,
user_id
:
bson
.
ObjectId
)
->
bool
:
"""Returns True iff the user has Attract User role."""
from
pillar
import
current_app
from
pillar.auth
import
UserClass
assert
isinstance
(
user_id
,
bson
.
ObjectId
)
# TODO: move role checking code to Pillar.
users_coll
=
current_app
.
db
(
'users'
)
db_user
=
users_coll
.
find_one
({
'_id'
:
user_id
},
{
'roles'
:
1
})
if
not
db_user
:
self
.
_log
.
debug
(
'user_is_attract_user: User
%s
not found'
,
user_id
)
return
False
user
=
UserClass
.
construct
(
''
,
db_user
)
return
user
.
has_cap
(
'attract-use'
)
def
current_user_may
(
self
,
action
:
Actions
,
project_id
:
bson
.
ObjectId
=
None
)
->
bool
:
"""Returns True iff the user is authorised to use/view Attract on the current project.
Requires that determine_user_rights() was called before.
"""
try
:
attract_rights
=
flask
.
g
.
attract_rights
except
AttributeError
:
if
not
project_id
:
self
.
_log
.
error
(
'current_user_may() called without previous call '
'to current_user_rights()'
)
return
False
self
.
determine_user_rights
(
project_id
)
attract_rights
=
flask
.
g
.
attract_rights
return
action
in
attract_rights
def
determine_user_rights
(
self
,
project_id
:
bson
.
ObjectId
):
"""Updates g.attract_rights to reflect the current user's usage rights.
g.attract_rights is a frozenset that contains zero or more Actions.
"""
from
pillar.auth
import
current_user
from
pillar.api.projects.utils
import
user_rights_in_project
if
current_user
.
is_anonymous
:
self
.
_log
.
debug
(
'Anonymous user never has access to Attract.'
)
flask
.
g
.
attract_rights
=
frozenset
()
return
rights
=
set
()
for
action
in
Actions
:
cap
=
req_cap
[
action
]
if
current_user
.
has_cap
(
cap
):
rights
.
add
(
action
)
# TODO Sybren: possibly split this up into a manager-fetching func + authorisation func.
# TODO: possibly store the user rights on the current project in the current_user object?
allowed_on_proj
=
user_rights_in_project
(
project_id
)
if
not
allowed_on_proj
.
intersection
(
PROJECT_METHODS_TO_USE_ATTRACT
):
rights
.
discard
(
Actions
.
USE
)
flask
.
g
.
attract_rights
=
frozenset
(
rights
)
File Metadata
Details
Attached
Mime Type
text/x-python
Expires
Thu, Jul 7, 6:31 AM (2 d)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
33/09/fc34292ebf5856fb12806464ccad
Attached To
rA Attract
Event Timeline
Log In to Comment