Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
webservices
cern-search
cern-search-rest-api
Commits
45c46fbd
Commit
45c46fbd
authored
May 14, 2018
by
Pablo Panero
Browse files
Admin permission
parent
a35dfa4a
Changes
5
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
45c46fbd
...
...
@@ -24,3 +24,7 @@ secrets/
# Local env source
env.sh
# Debug and other logs
*.log
cern_search_rest/config.py
View file @
45c46fbd
...
...
@@ -30,10 +30,23 @@ CERN_REMOTE_APP["params"].update(dict(request_token_params={
"scope"
:
"Name Email Bio Groups"
,
}))
CERN_REMOTE_APP
[
"authorized_handler"
]
=
'cern_search_rest.modules.cernsearch.handlers:cern_authorized_signup_handler'
OAUTHCLIENT_REMOTE_APPS
=
dict
(
cern
=
CERN_REMOTE_APP
,
)
# Accounts
# ========
# FIXME: Needs to be disable for role base auth in SSO. If not invenio_account/sessions:login_listener will crash
ACCOUNTS_SESSION_ACTIVITY_ENABLED
=
False
# Admin
# =====
ADMIN_PERMISSION_FACTORY
=
'cern_search_rest.modules.cernsearch.permissions:admin_permission_factory'
# JSON Schemas configuration
# ==========================
...
...
@@ -98,7 +111,6 @@ RECORDS_REST_ENDPOINTS = dict(
)
)
# Flask Security
# ==============
# Avoid error upon registration with email sending
...
...
@@ -106,3 +118,5 @@ RECORDS_REST_ENDPOINTS = dict(
SECURITY_SEND_REGISTER_EMAIL
=
False
SECURITY_CONFIRM_REGISTRATION
=
False
SECURITY_CONFIRMABLE
=
False
SECURITY_REGISTERABLE
=
False
# Avoid user registration outside of CERN SSO
SECURITY_RECOVERABLE
=
False
# Avoid user password recovery
cern_search_rest/modules/cernsearch/handlers.py
0 → 100644
View file @
45c46fbd
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""Handlers for customizing oauthclient endpoints."""
from
__future__
import
absolute_import
,
print_function
from
flask
import
current_app
,
redirect
,
session
,
url_for
,
g
,
after_this_request
from
flask_login
import
current_user
,
user_logged_in
from
flask_security
import
logout_user
from
flask_security.utils
import
get_post_logout_redirect
from
invenio_db
import
db
from
invenio_oauthclient.proxies
import
current_oauthclient
from
invenio_oauthclient.signals
import
account_info_received
,
account_setup_committed
,
\
account_setup_received
from
invenio_oauthclient.utils
import
oauth_authenticate
,
oauth_get_user
,
create_csrf_disabled_registrationform
,
\
fill_form
,
oauth_register
from
invenio_oauthclient.handlers
import
oauth_error_handler
,
token_session_key
,
response_token_setter
,
\
token_getter
,
get_session_next_url
from
cern_search_rest.modules.cernsearch.utils
import
get_user_provides
@
oauth_error_handler
def
cern_authorized_signup_handler
(
resp
,
remote
,
*
args
,
**
kwargs
):
"""Handle sign-in/up functionality.
:param remote: The remote application.
:param resp: The response.
:returns: Redirect response.
"""
# Remove any previously stored auto register session key
session
.
pop
(
token_session_key
(
remote
.
name
)
+
'_autoregister'
,
None
)
# Store token in session
# ----------------------
# Set token in session - token object only returned if
# current_user.is_autenticated().
token
=
response_token_setter
(
remote
,
resp
)
handlers
=
current_oauthclient
.
signup_handlers
[
remote
.
name
]
# Sign-in/up user
# ---------------
if
not
current_user
.
is_authenticated
:
account_info
=
handlers
[
'info'
](
resp
)
account_info_received
.
send
(
remote
,
token
=
token
,
response
=
resp
,
account_info
=
account_info
)
user
=
oauth_get_user
(
remote
.
consumer_key
,
account_info
=
account_info
,
access_token
=
token_getter
(
remote
)[
0
],
)
if
user
is
None
:
# Auto sign-up if user not found
form
=
create_csrf_disabled_registrationform
()
form
=
fill_form
(
form
,
account_info
[
'user'
]
)
user
=
oauth_register
(
form
)
# if registration fails ...
if
user
is
None
:
# requires extra information
session
[
token_session_key
(
remote
.
name
)
+
'_autoregister'
]
=
True
session
[
token_session_key
(
remote
.
name
)
+
'_account_info'
]
=
account_info
session
[
token_session_key
(
remote
.
name
)
+
'_response'
]
=
resp
db
.
session
.
commit
()
return
redirect
(
url_for
(
'.signup'
,
remote_app
=
remote
.
name
,
))
# Authenticate user
if
not
oauth_authenticate
(
remote
.
consumer_key
,
user
,
require_existing_link
=
False
):
return
current_app
.
login_manager
.
unauthorized
()
# Link account
# ------------
# Need to store token in database instead of only the session when
# called first time.
token
=
response_token_setter
(
remote
,
resp
)
# Setup account
# -------------
if
not
token
.
remote_account
.
extra_data
:
account_setup
=
handlers
[
'setup'
](
token
,
resp
)
account_setup_received
.
send
(
remote
,
token
=
token
,
response
=
resp
,
account_setup
=
account_setup
)
db
.
session
.
commit
()
account_setup_committed
.
send
(
remote
,
token
=
token
)
else
:
db
.
session
.
commit
()
# Redirect to next
if
current_user
.
is_authenticated
and
not
egroup_admin
():
logout_user
()
return
redirect
(
get_post_logout_redirect
())
next_url
=
get_session_next_url
(
remote
.
name
)
if
next_url
:
return
redirect
(
next_url
)
return
redirect
(
url_for
(
'invenio_oauthclient_settings.index'
))
def
egroup_admin
():
admin_access_groups
=
current_app
.
config
[
'ADMIN_VIEW_ACCESS_GROUPS'
]
# Allow based in the '_access' key
user_provides
=
get_user_provides
()
# set.isdisjoint() is faster than set.intersection()
admin_access_groups
=
admin_access_groups
.
split
(
','
)
if
user_provides
and
not
set
(
user_provides
).
isdisjoint
(
set
(
admin_access_groups
)):
return
True
return
False
cern_search_rest/modules/cernsearch/permissions.py
View file @
45c46fbd
...
...
@@ -2,9 +2,11 @@
# -*- coding: utf-8 -*-
from
flask_security
import
current_user
from
flask
import
request
,
g
from
flask
import
request
,
g
,
current_app
from
invenio_search
import
current_search_client
from
cern_search_rest.modules.cernsearch.utils
import
get_user_provides
"""Access control for CERN Search."""
...
...
@@ -136,6 +138,45 @@ def has_delete_permission(user, record):
return
False
"""Access control for CERN Search Admin Web UI."""
def
admin_permission_factory
(
view
):
"""Record permission factory."""
return
AdminPermission
.
create
(
view
=
view
)
class
AdminPermission
(
object
):
def
__init__
(
self
,
func
,
user
,
view
):
"""Initialize a file permission object."""
self
.
user
=
user
or
current_user
self
.
func
=
func
self
.
view
=
view
def
can
(
self
):
"""Determine access."""
return
self
.
func
(
self
.
user
)
@
classmethod
def
create
(
cls
,
user
=
None
,
view
=
None
):
"""Create a record permission."""
# Allow everything for testing
return
cls
(
has_admin_view_permission
,
user
,
view
)
def
has_admin_view_permission
(
user
):
admin_access_groups
=
current_app
.
config
[
'ADMIN_VIEW_ACCESS_GROUPS'
]
if
user
.
is_authenticated
and
admin_access_groups
:
# Allow based in the '_access' key
user_provides
=
get_user_provides
()
# set.isdisjoint() is faster than set.intersection()
admin_access_groups
=
admin_access_groups
.
split
(
','
)
if
user_provides
and
not
set
(
user_provides
).
isdisjoint
(
set
(
admin_access_groups
)):
return
True
return
False
# Utility functions
...
...
@@ -155,8 +196,3 @@ def is_public(data, action):
the action is not inside access or is empty.
"""
return
'_access'
not
in
data
or
not
data
.
get
(
'_access'
,
{}).
get
(
action
)
def
get_user_provides
():
"""Extract the user's provides from g."""
return
[
need
.
value
for
need
in
g
.
identity
.
provides
]
template/cern-search-api.yml
View file @
45c46fbd
...
...
@@ -337,18 +337,22 @@ objects:
INVENIO_THEME_SITENAME
:
${SITE_NAME}
INVENIO_THEME_LOGO
:
${LOGO_PATH}
INVENIO_THEME_LOGO_ADMIN
:
${LOGO_PATH}
INVENIO_ADMIN_VIEW_ACCESS_GROUPS
:
${ADMIN_UI_ACCESS_LIST}
parameters
:
-
name
:
APP_INSTANCE_PATH
description
:
"
Invenio
instance
path
for
CERN
Search
application."
required
:
tru
e
value
:
/usr/local/var/cernsearch/var/cernsearch-instanc
e
-
name
:
APP_ALLOWED_HOSTS
description
:
"
Invenio
App
allowed
hosts.
Without
protocol
(e.g.
http)
nor
salsh
('/')
at
the
end"
required
:
true
value
:
[
'
test-cern-search.web.cern.ch'
]
-
name
:
SITE_NAME
description
:
"
CERN
Search
site
name
(E.g.
EDMS,
Indico,
etc.)"
required
:
true
description
:
"
CERN
Search
site
name
(E.g.
EDMS,
Indico,
etc.)"
value
:
CERN Search
-
name
:
LOGO_PATH
description
:
"
CERN
Search
site
logo
(E.g.
/images/cernsearchicon.png)"
required
:
true
\ No newline at end of file
description
:
"
CERN
Search
site
logo
(E.g.
/images/cernsearchicon.png)"
value
:
/images/cernsearchicon.png
-
name
:
ADMIN_UI_ACCESS_LIST
description
:
"
List
of
comma
separated
egroups
that
have
access
to
the
ADMIN
UI
(e.g.
'egroup_one,egroup_two')"
value
:
"
CernSearch-Administrators"
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