Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
feudal
feudalBackend
Commits
1c64600c
Commit
1c64600c
authored
Jun 22, 2018
by
Lukas Burgey
Browse files
Update userinfo of users
parent
a6ae9e38
Changes
5
Hide whitespace changes
Inline
Side-by-side
django_backend/backend/auth/v1/client_views.py
View file @
1c64600c
...
...
@@ -75,7 +75,7 @@ def _webpage_client_valid(request):
):
return
True
LOGGER
.
error
(
'Failed to authenticate webpage client for RabbitMQ'
)
#
LOGGER.error('Failed to authenticate webpage client for RabbitMQ')
return
False
# VIEWS: authentication and authorization for
...
...
@@ -83,14 +83,14 @@ def _webpage_client_valid(request):
def
user_endpoint
(
request
):
if
_webpage_client_valid
(
request
):
#
LOGGER.info('Authenticated webpage client')
LOGGER
.
info
(
'Authenticated webpage client'
)
return
ALLOW
user
=
authenticate
(
username
=
request
.
POST
.
get
(
'username'
),
password
=
request
.
POST
.
get
(
'password'
),
)
if
user
:
if
user
is
not
None
:
LOGGER
.
info
(
'Authenticated client as %s'
,
user
)
return
ALLOW
...
...
@@ -175,7 +175,6 @@ def resource_endpoint(request):
)
return
DENY
def
topic_endpoint
(
request
):
permission
=
request
.
POST
.
get
(
'permission'
,
[])
resource
=
request
.
POST
.
get
(
'resource'
,
''
)
...
...
@@ -215,9 +214,8 @@ def topic_endpoint(request):
match
=
re
.
search
(
'service.(.+)'
,
routing_key
)
if
match
:
service_name
=
match
.
group
(
1
)
for
service
in
user
.
site
.
services
.
all
():
if
service_name
==
service
.
name
:
return
ALLOW
if
user
.
site
.
services
.
filter
(
name
=
service_name
).
exists
():
return
ALLOW
elif
name
==
'sites'
:
if
routing_key
==
user
.
site
.
name
:
return
ALLOW
...
...
django_backend/backend/auth/v1/models.py
View file @
1c64600c
import
logging
import
json
from
urllib.request
import
Request
,
urlopen
from
django.core.exceptions
import
ObjectDoesNotExist
from
django.db
import
models
as
db_models
from
django_mysql.models
import
JSONField
from
oic.oic
import
Client
from
oic.oic.message
import
RegistrationResponse
from
oic.utils.authn.client
import
CLIENT_AUTHN_METHOD
...
...
@@ -13,6 +13,9 @@ LOGGER = logging.getLogger(__name__)
OIDC_CLIENT
=
{}
def
scopes_default
():
return
[]
class
OIDCConfig
(
db_models
.
Model
):
client_id
=
db_models
.
CharField
(
max_length
=
200
)
...
...
@@ -25,6 +28,13 @@ class OIDCConfig(db_models.Model):
# does this idp provide us with group informations?
group_provider
=
db_models
.
BooleanField
(
default
=
False
)
# scopes as a list of strings
scopes
=
JSONField
(
default
=
scopes_default
,
editable
=
True
,
)
@
property
def
registration_response
(
self
):
info
=
{
...
...
@@ -55,13 +65,13 @@ class OIDCConfig(db_models.Model):
args
=
{
'client_id'
:
self
.
client_id
,
'response_type'
:
'code'
,
'scope'
:
[
'openid'
,
'profile'
,
'email'
,
'credentials'
]
,
'scope'
:
self
.
scopes
,
'redirect_uri'
:
self
.
redirect_uri
,
'state'
:
state
,
}
auth_req
=
client
.
construct_AuthorizationRequest
(
request_args
=
args
request_args
=
args
,
)
return
auth_req
.
request
(
client
.
authorization_endpoint
)
...
...
@@ -79,12 +89,12 @@ def default_idp():
class
OIDCTokenAuthBackend
(
object
):
def
get_userinfo
(
self
,
request
,
oidc_client
,
access_token
=
''
,
state
=
None
):
def
get_userinfo
(
self
,
oidc_client
,
access_token
=
None
):
user_info
=
None
if
access_token
is
not
None
:
req
=
Request
(
oidc_client
.
provider_info
[
'userinfo_endpoint'
]
+
'?scope=openid&scope=profile'
,
oidc_client
.
provider_info
[
'userinfo_endpoint'
],
)
auth
=
(
'Bearer '
+
access_token
)
req
.
add_header
(
'Authorization'
,
auth
)
...
...
@@ -108,25 +118,33 @@ class OIDCTokenAuthBackend(object):
# get the user info from the idp
userinfo
=
self
.
get_userinfo
(
request
,
oidc_client
,
access_token
=
token
,
)
try
:
return
models
.
User
.
get_user
(
userinfo
,
oidc_client
,
)
except
Exception
as
exception
:
LOGGER
.
error
(
'OIDCTokenAuthBackend: error constructing user: %s'
,
exception
)
return
None
return
models
.
User
.
get_user
(
userinfo
,
oidc_client
,
)
def
get_user
(
self
,
user_id
):
try
:
return
models
.
User
.
objects
.
get
(
user_type
=
'oidcuser'
,
pk
=
user_id
query
=
models
.
User
.
objects
.
filter
(
user_type
=
'oidcuser'
,
pk
=
user_id
)
if
query
.
exists
():
if
len
(
query
)
==
1
:
return
query
.
first
()
LOGGER
.
error
(
'OIDCTokenAuthBackend: query for user id %s: %s results'
,
user_id
,
len
(
query
),
)
except
ObjectDoesNotExist
:
return
None
LOGGER
.
error
(
'OIDCTokenAuthBackend: query for user id %s: no results'
,
user_id
,
)
return
None
django_backend/backend/auth/v1/views.py
View file @
1c64600c
...
...
@@ -89,24 +89,6 @@ class AuthCallback(View):
},
)
)
# FIXME 'email_verified' in user info is no boolean
# but oic expects it to be
#user_info = oidc_client.do_user_info_request(
# method="GET",
# state=state,
#)
#LOGGER.debug("EXPERIMENT: %s", user_info)
# user_info = self.get_user_info(ac_token_response['access_token'])
# try:
# u = models.User.objects.get(sub=user_info['sub'])
# except:
# u = models.user_from_user_info(user_info)
# u.save()
# response = render(request, 'backend/index.html', context)
user
=
authenticate
(
request
,
token
=
ac_token_response
[
'access_token'
],
...
...
@@ -117,13 +99,11 @@ class AuthCallback(View):
if
user
is
None
:
# authentication failed -> "401"
LOGGER
.
error
(
'User failed to log in'
)
utils
.
set_session
(
request
,
'error'
,
'Login failed'
)
# response = HttpResponse('Unauthorized', status=401)
request
.
session
[
'error'
]
=
'Authentication failed'
elif
not
user
.
is_active
:
# user is deactivated -> "403"
LOGGER
.
info
(
'%s tried to log in'
,
user
)
utils
.
set_session
(
request
,
'error'
,
'Account deactivated'
)
# response = HttpResponse('Forbidden', status=403)
request
.
session
[
'error'
]
=
'Account deactivated'
else
:
# user authenticated -> back to frontend
login
(
request
,
user
)
...
...
django_backend/backend/frontend/views.py
View file @
1c64600c
import
logging
from
django.shortcuts
import
get_object_or_404
from
django.core.exceptions
import
ObjectDoesNotExist
from
django.contrib.auth
import
logout
from
rest_framework
import
views
from
rest_framework.permissions
import
AllowAny
...
...
@@ -35,22 +34,6 @@ def _api_state_response_data(request):
'user_state'
:
user_state
(
request
.
user
),
}
# Response for StateView, LogoutView, and all post requests
def
_api_state_response
(
request
):
if
not
request
.
user
.
is_authenticated
:
return
Response
({
'user_state'
:
None
,
})
response
=
_api_state_response_data
(
request
)
if
'error'
in
request
.
session
:
response
[
'error'
]
=
request
.
session
[
'error'
]
# we display errors only once
del
request
.
session
[
'error'
]
return
Response
(
response
)
def
state_view_data
(
request
):
data
=
{}
if
request
.
user
.
is_authenticated
:
...
...
@@ -66,6 +49,12 @@ def state_view_data(request):
data
[
'user'
]
=
None
data
[
'user_state'
]
=
None
data
[
'services'
]
=
[]
if
'error'
in
request
.
session
:
data
[
'error'
]
=
request
.
session
[
'error'
]
# we display errors only once
del
request
.
session
[
'error'
]
return
data
...
...
@@ -161,7 +150,7 @@ class QuestionnaireView(views.APIView):
else
:
LOGGER
.
error
(
'Received questionnaire answer for non existing item'
)
return
_api_state_response
(
request
)
return
Response
(
state_view_data
(
request
)
)
class
UserDeletionView
(
views
.
APIView
):
...
...
django_backend/backend/models.py
View file @
1c64600c
...
...
@@ -280,19 +280,22 @@ class User(AbstractUser):
if
'sub'
not
in
userinfo
:
raise
Exception
(
'get_user needs a userinfo which contains the users subject'
)
query
_result
=
cls
.
objects
.
filter
(
query
=
cls
.
objects
.
filter
(
sub
=
userinfo
[
'sub'
],
idp
=
idp
,
)
if
not
query
_result
.
exists
():
if
not
query
.
exists
():
return
cls
.
construct_from_userinfo
(
userinfo
,
idp
)
if
len
(
query
_result
)
>
1
:
if
len
(
query
)
>
1
:
return
Exception
(
'Two user instances with same subject from the same idp'
)
# TODO update the users userinfo when it changes
# TODO update the users groupinfo when it changes
return
query_result
.
first
()
user
=
query
.
first
()
# update the users userinfo
user
.
userinfo
=
userinfo
user
.
save
()
return
user
@
classmethod
def
construct_from_userinfo
(
cls
,
userinfo
,
idp
):
...
...
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