Exemplo n.º 1
0
def create_user_info(client, user, scope_set, id_token=False):
    '''Create user info dictionnary'''
    user_info = {'sub': make_sub(client, user)}
    attributes = get_attributes({
        'user':
        user,
        'request':
        None,
        'service':
        client,
        '__wanted_attributes':
        client.get_wanted_attributes()
    })
    for claim in client.oidcclaim_set.filter(name__isnull=False):
        if not set(claim.get_scopes()).intersection(scope_set):
            continue
        if not claim.value in attributes:
            continue
        user_info[claim.name] = normalize_claim_values(attributes[claim.value])
        # check if attribute is verified
        if claim.value + ':verified' in attributes:
            user_info[claim.value + '_verified'] = True
    hooks.call_hooks('idp_oidc_modify_user_info', client, user, scope_set,
                     user_info)
    return user_info
Exemplo n.º 2
0
 def form_valid(self, form):
     response = super(RoleDeleteView, self).form_valid(form)
     hooks.call_hooks('event',
                      name='manager-delete-role',
                      user=self.request.user,
                      role=form.instance)
     return response
Exemplo n.º 3
0
 def form_valid(self, form):
     RoleParenting = get_role_parenting_model()
     role = form.cleaned_data['role']
     action = form.cleaned_data['action']
     if self.can_change:
         if action == 'add':
             if RoleParenting.objects.filter(parent=self.object,
                                             child=role,
                                             direct=True).exists():
                 messages.warning(
                     self.request,
                     _('Role "%s" is already a '
                       'child of this role.') % role.name)
             else:
                 self.object.add_child(role)
                 hooks.call_hooks('event',
                                  name='manager-add-child-role',
                                  user=self.request.user,
                                  parent=self.object,
                                  child=role)
         elif action == 'remove':
             hooks.call_hooks('event',
                              name='manager-remove-child-role',
                              user=self.request.user,
                              parent=self.object,
                              child=role)
             self.object.remove_child(role)
     else:
         messages.warning(self.request, _('You are not authorized'))
     return super(RoleChildrenView, self).form_valid(form)
Exemplo n.º 4
0
 def form_valid(self, form):
     user = form.cleaned_data['user']
     action = form.cleaned_data['action']
     if self.can_change:
         if action == 'add':
             if self.object.members.filter(pk=user.pk).exists():
                 messages.warning(self.request,
                                  _('User already in this role.'))
             else:
                 self.object.members.add(user)
                 hooks.call_hooks('event',
                                  name='manager-add-role-member',
                                  user=self.request.user,
                                  role=self.object,
                                  member=user)
         elif action == 'remove':
             if not self.object.members.filter(pk=user.pk).exists():
                 messages.warning(self.request,
                                  _('User was not in this role.'))
             else:
                 self.object.members.remove(user)
                 hooks.call_hooks('event',
                                  name='manager-remove-role-member',
                                  user=self.request.user,
                                  role=self.object,
                                  member=user)
     else:
         messages.warning(self.request, _('You are not authorized'))
     return super(RoleMembersView, self).form_valid(form)
Exemplo n.º 5
0
 def form_valid(self, form):
     response = super(RoleAddView, self).form_valid(form)
     hooks.call_hooks('event',
                      name='manager-add-role',
                      user=self.request.user,
                      instance=form.instance,
                      form=form)
     return response
Exemplo n.º 6
0
 def post(self, request, *args, **kwargs):
     self.object.get_admin_role().members.remove(self.user)
     hooks.call_hooks('event',
                      name='remove-remove-admin-role-user',
                      user=self.request.user,
                      role=self.object,
                      admin=self.user)
     return redirect(self.request, self.success_url)
Exemplo n.º 7
0
 def post(self, request, *args, **kwargs):
     self.object.get_admin_role().remove_child(self.child)
     hooks.call_hooks('event',
                      name='manager-remove-admin-role',
                      user=self.request.user,
                      role=self.object,
                      admin_role=self.child)
     return redirect(self.request, self.success_url)
Exemplo n.º 8
0
 def post(self, request, *args, **kwargs):
     self.object.remove_child(self.child)
     hooks.call_hooks('event',
                      name='manager-remove-child-role',
                      user=self.request.user,
                      parent=self.object,
                      child=self.child)
     return redirect(self.request, self.success_url)
Exemplo n.º 9
0
 def form_valid(self, form):
     administered_role = self.get_object()
     for user in form.cleaned_data['users']:
         administered_role.get_admin_role().members.add(user)
         hooks.call_hooks('event',
                          name='manager-add-admin-role-user',
                          user=self.request.user,
                          role=administered_role,
                          admin=user)
     return super(RoleAddAdminUserView, self).form_valid(form)
Exemplo n.º 10
0
 def form_valid(self, form):
     administered_role = self.get_object()
     for role in form.cleaned_data['roles']:
         administered_role.get_admin_role().add_child(role)
         hooks.call_hooks('event',
                          name='manager-add-admin-role',
                          user=self.request.user,
                          role=administered_role,
                          admin_role=role)
     return super(RoleAddAdminRoleView, self).form_valid(form)
Exemplo n.º 11
0
 def post(self, request, *args, **kwargs):
     if not self.request.user.has_perm('a2_rbac.change_role', self.parent):
         raise PermissionDenied
     self.object.remove_parent(self.parent)
     hooks.call_hooks('event',
                      name='manager-remove-child-role',
                      user=self.request.user,
                      parent=self.parent,
                      child=self.object)
     return redirect(self.request, self.success_url)
Exemplo n.º 12
0
 def form_valid(self, form):
     child = self.get_object()
     for role in form.cleaned_data['roles']:
         child.add_parent(role)
         hooks.call_hooks('event',
                          name='manager-add-child-role',
                          user=self.request.user,
                          parent=role,
                          child=child)
     return super(RoleAddParentView, self).form_valid(form)
Exemplo n.º 13
0
    def get_displayed_other_actions(self):
        actions = []
        other_actions = list(self.get_other_actions())
        hooks.call_hooks('manager_modify_other_actions', self, other_actions)
        for action in other_actions:
            if callable(action.display) and not action.display(
                    self.object, self.request):
                continue

            if action.display:
                actions.append(action)
        return actions
Exemplo n.º 14
0
 def form_valid(self, form):
     models.DeletedUser.objects.delete_user(self.request.user)
     self.request.user.email += '#%d' % random.randint(1, 10000000)
     self.request.user.email_verified = False
     self.request.user.save(update_fields=['email', 'email_verified'])
     logger.info(u'deletion of account %s requested', self.request.user)
     hooks.call_hooks('event',
                      name='delete-account',
                      user=self.request.user)
     messages.info(
         self.request,
         _('Your account has been scheduled for deletion. You cannot use it anymore.'
           ))
     return super(DeleteView, self).form_valid(form)
Exemplo n.º 15
0
    def get(self, request):
        '''Continue CAS login after authentication'''
        service = request.GET.get(SERVICE_PARAM)
        ticket_id = request.GET.get(NONCE_FIELD_NAME)
        cancel = request.GET.get(CANCEL_PARAM) is not None
        if ticket_id is None:
            return self.failure(request, service, 'missing ticket id')
        if not ticket_id.startswith(SERVICE_TICKET_PREFIX):
            return self.failure(request, service, 'invalid ticket id')
        try:
            st = Ticket.objects.select_related('service',
                                               'user').get(ticket_id=ticket_id)
        except Ticket.DoesNotExist:
            return self.failure(request, service, 'unknown ticket id')
        # no valid ticket should be submitted to continue, delete them !
        if st.valid():
            st.delete()
            return self.failure(
                request, service,
                'ticket %r already valid passed to continue' % st.ticket_id)
        # service URL mismatch
        if st.service_url != service:
            st.delete()
            return self.failure(
                request, service,
                'ticket service does not match service parameter')
        # user asked for cancellation
        if cancel:
            st.delete()
            self.logger.debug('login from %s canceled', service)
            return redirect(request, service)
        # Not logged in ? Authenticate again
        if not request.user.is_authenticated():
            return self.authenticate(request, st)
        # Renew requested and ticket is unknown ? Try again
        if st.renew and not find_authentication_event(request, st.ticket_id):
            return self.authenticate(request, st)
        # if user not authorized, a ServiceAccessDenied exception
        # is raised and handled by ServiceAccessMiddleware
        st.service.authorize(request.user)

        self.validate_ticket(request, st)
        if st.valid():
            hooks.call_hooks('event',
                             name='sso-success',
                             service=st.service,
                             user=st.user)
            return redirect(request, service, params={'ticket': st.ticket_id})
        # Should not happen
        assert False
Exemplo n.º 16
0
 def registration_success(self, request, user, form):
     hooks.call_hooks('event',
                      name='registration',
                      user=user,
                      form=form,
                      view=self,
                      authentication_method=self.authentication_method,
                      token=request.token,
                      service=self.service)
     simulate_authentication(request,
                             user,
                             method=self.authentication_method,
                             service_slug=self.service)
     messages.info(self.request, _('You have just created an account.'))
     self.send_registration_success_email(user)
     return redirect(request, self.get_success_url())
Exemplo n.º 17
0
    def get(self, request):
        service = request.GET.get(SERVICE_PARAM)
        renew = request.GET.get(RENEW_PARAM) is not None
        gateway = request.GET.get(GATEWAY_PARAM) is not None

        if not service:
            return self.failure(request, '', 'no service field')
        model = Service.objects.for_service(service)
        if not model:
            return self.failure(request, service, 'service unknown')
        if renew and gateway:
            return self.failure(
                request, service, 'renew and gateway cannot be requested '
                'at the same time')

        hooks.call_hooks('event', name='sso-request', service=model)

        st = Ticket()
        st.service = model
        # Limit size of return URL to an acceptable length
        service = service[:4096]
        st.service_url = service
        st.renew = renew
        self.logger.debug('login request from %r renew: %s gateway: %s',
                          service, renew, gateway)
        if self.must_authenticate(request, renew, gateway):
            st.save()
            return self.authenticate(request, st)
        self.validate_ticket(request, st)
        if st.valid():
            st.save()
            hooks.call_hooks('event',
                             name='sso-success',
                             service=model,
                             user=request.user)
            return redirect(request, service, params={'ticket': st.ticket_id})
        self.logger.debug('gateway requested but no session is open')
        return redirect(request, service)
Exemplo n.º 18
0
 def form_valid(self, form):
     if self.can_change:
         operation = form.cleaned_data.get('operation')
         ou = form.cleaned_data.get('ou')
         target = form.cleaned_data.get('target')
         action = form.cleaned_data.get('action')
         Permission = get_permission_model()
         if action == 'add' and operation and target:
             perm, created = Permission.objects \
                 .get_or_create(operation=operation, ou=ou,
                                target_ct=ContentType.objects.get_for_model(
                                    target),
                                target_id=target.pk)
             self.object.permissions.add(perm)
             hooks.call_hooks('event',
                              name='manager-add-permission',
                              user=self.request.user,
                              role=self.object,
                              permission=perm)
         elif action == 'remove':
             try:
                 permission_id = int(self.request.POST.get(
                     'permission', ''))
                 perm = Permission.objects.get(id=permission_id)
             except (ValueError, Permission.DoesNotExist):
                 pass
             else:
                 if self.object.permissions.filter(
                         id=permission_id).exists():
                     self.object.permissions.remove(perm)
                     hooks.call_hooks('event',
                                      name='manager-remove-permission',
                                      user=self.request.user,
                                      role=self.object,
                                      permission=perm)
     else:
         messages.warning(self.request, _('You are not authorized'))
     return super(RolePermissionsView, self).form_valid(form)
Exemplo n.º 19
0
 def post(self, request, *args, **kwargs):
     self.object = self.get_object()
     for action in self.get_displayed_other_actions():
         if action.name in request.POST:
             response = None
             if hasattr(action, 'do'):
                 response = action.do(self, request, self.object)
             else:
                 method = getattr(self, 'action_' + action.name, None)
                 if method:
                     response = method(request, *args, **kwargs)
             hooks.call_hooks('event',
                              name='manager-action',
                              user=self.request.user,
                              action=action,
                              instance=self.object)
             if response:
                 return response
             self.request.method = 'GET'
             return self.get(request, *args, **kwargs)
     parent = super(OtherActionsMixin, self)
     if hasattr(parent, 'post'):
         return parent.post(request, *args, **kwargs)
     return self.get(request, *args, **kwargs)
Exemplo n.º 20
0
 def get_homepage_entries(self):
     entries = []
     for entry in self.default_entries:
         if 'permission' in entry and not self.request.user.has_perm_any(
                 entry['permission']):
             continue
         entries.append(entry)
     for hook_entries in hooks.call_hooks('manager_homepage_entries', self):
         if not hasattr(hook_entries, 'append'):
             hook_entries = [hook_entries]
         for entry in hook_entries:
             if 'permission' in entry and not self.request.user.has_perm_any(
                     entry['permission']):
                 continue
             entries.append(entry)
     # use possible key order to sort
     # list.sort() is supposed to be a stable sort (already sorted entries
     # are kept in the same order)
     entries.sort(key=lambda d: d.get('order', 0))
     return entries
Exemplo n.º 21
0
 def get_form(self, form_class=None):
     form = super(RegistrationCompletionView,
                  self).get_form(form_class=form_class)
     hooks.call_hooks('front_modify_form', self, form)
     return form
Exemplo n.º 22
0
def authorize(request, *args, **kwargs):
    logger = logging.getLogger(__name__)
    start = now()

    try:
        client_id = request.GET['client_id']
        redirect_uri = request.GET['redirect_uri']
    except KeyError as k:
        return HttpResponseBadRequest('invalid request: missing parameter %s' % k.args[0],
                                      content_type='text/plain')
    try:
        client = models.OIDCClient.objects.get(client_id=client_id)
    except models.OIDCClient.DoesNotExist:
        return HttpResponseBadRequest('invalid request: unknown client_id', content_type='text/plain')
    fragment = client.authorization_flow == client.FLOW_IMPLICIT

    state = request.GET.get('state')

    try:
        response_type = request.GET['response_type']
        scope = request.GET['scope']
    except KeyError as k:
        return authorization_error(request, redirect_uri, 'invalid_request',
                                   state=state,
                                   error_description='missing parameter %s' % k.args[0],
                                   fragment=fragment)

    prompt = set(filter(None, request.GET.get('prompt', '').split()))
    nonce = request.GET.get('nonce')
    scopes = utils.scope_set(scope)

    max_age = request.GET.get('max_age')
    if max_age:
        try:
            max_age = int(max_age)
            if max_age < 0:
                raise ValueError
        except ValueError:
            return authorization_error(request, redirect_uri, 'invalid_request',
                                       error_description='max_age is not a positive integer',
                                       state=state,
                                       fragment=fragment)

    if redirect_uri not in client.redirect_uris.split():
        return authorization_error(request, redirect_uri, 'invalid_request',
                                   error_description='unauthorized redirect_uri',
                                   state=state,
                                   fragment=fragment)
    if client.authorization_flow == client.FLOW_AUTHORIZATION_CODE:
        if response_type != 'code':
            return authorization_error(request, redirect_uri, 'unsupported_response_type',
                                       error_description='only code is supported',
                                       state=state,
                                       fragment=fragment)
    elif client.authorization_flow == client.FLOW_IMPLICIT:
        if not set(filter(None, response_type.split())) in (set(['id_token', 'token']),
                                                            set(['id_token'])):
            return authorization_error(request, redirect_uri, 'unsupported_response_type',
                                       error_description='only "id_token token" or "id_token" '
                                       'are supported',
                                       state=state,
                                       fragment=fragment)
    else:
        raise NotImplementedError
    if 'openid' not in scopes:
        return authorization_error(request, redirect_uri, 'invalid_request',
                                   error_description='openid scope is missing',
                                   state=state,
                                   fragment=fragment)
    allowed_scopes = app_settings.SCOPES or ['openid', 'email', 'profile']
    if not (scopes <= set(allowed_scopes)):
        message = 'only "%s" scope(s) are supported, but "%s" requested' % (
            ', '.join(allowed_scopes), ', '.join(scopes))
        return authorization_error(request, redirect_uri, 'invalid_scope',
                                   error_description=message,
                                   state=state,
                                   fragment=fragment)

    hooks.call_hooks('event', name='sso-request', idp='oidc', service=client)
    # authentication canceled by user
    if 'cancel' in request.GET:
        logger.info(u'authentication canceled for service %s', client.name)
        return authorization_error(request, redirect_uri, 'access_denied',
                                   error_description='user did not authenticate',
                                   state=state,
                                   fragment=fragment)

    if not request.user.is_authenticated() or 'login' in prompt:
        if 'none' in prompt:
            return authorization_error(request, redirect_uri, 'login_required',
                                       error_description='login is required but prompt is none',
                                       state=state,
                                       fragment=fragment)
        params = {}
        if nonce is not None:
            params['nonce'] = nonce
        return login_require(request, params=params, service=client)

    # if user not authorized, a ServiceAccessDenied exception
    # is raised and handled by ServiceAccessMiddleware
    client.authorize(request.user)

    last_auth = last_authentication_event(request.session)
    if max_age is not None and time.time() - last_auth['when'] >= max_age:
        if 'none' in prompt:
            return authorization_error(request, redirect_uri, 'login_required',
                                       error_description='login is required but prompt is none',
                                       state=state,
                                       fragment=fragment)
        params = {}
        if nonce is not None:
            params['nonce'] = nonce
        return login_require(request, params=params, service=client)

    if client.authorization_mode != client.AUTHORIZATION_MODE_NONE or 'consent' in prompt:
        # authorization by user is mandatory, as per local configuration or per explicit request by
        # the RP
        if client.authorization_mode in (client.AUTHORIZATION_MODE_NONE,
                                         client.AUTHORIZATION_MODE_BY_SERVICE):
            auth_manager = client.authorizations
        elif client.authorization_mode == client.AUTHORIZATION_MODE_BY_OU:
            auth_manager = client.ou.oidc_authorizations

        qs = auth_manager.filter(user=request.user)

        if 'consent' in prompt:
            # if consent is asked we delete existing authorizations
            # it seems to be the safer option
            qs.delete()
            qs = auth_manager.none()
        else:
            qs = qs.filter(expired__gte=start)
        authorized_scopes = set()
        for authorization in qs:
            authorized_scopes |= authorization.scope_set()
        if (authorized_scopes & scopes) < scopes:
            if 'none' in prompt:
                return authorization_error(
                    request, redirect_uri, 'consent_required',
                    error_description='consent is required but prompt is none',
                    state=state,
                    fragment=fragment)
            if request.method == 'POST':
                if 'accept' in request.POST:
                    pk_to_deletes = []
                    for authorization in qs:
                        # clean obsolete authorizations
                        if authorization.scope_set() <= scopes:
                            pk_to_deletes.append(authorization.pk)
                    auth_manager.create(
                        user=request.user, scopes=u' '.join(sorted(scopes)),
                        expired=start + datetime.timedelta(days=365))
                    if pk_to_deletes:
                        auth_manager.filter(pk__in=pk_to_deletes).delete()
                    logger.info(u'authorized scopes %s for service %s', ' '.join(scopes),
                                client.name)
                else:
                    logger.info(u'refused scopes %s for service %s', ' '.join(scopes),
                                client.name)
                    return authorization_error(request, redirect_uri, 'access_denied',
                                               error_description='user denied access',
                                               state=state,
                                               fragment=fragment)
            else:
                return render(request, 'authentic2_idp_oidc/authorization.html',
                              {
                                  'client': client,
                                  'scopes': scopes - set(['openid']),
                              })
    if response_type == 'code':
        code = models.OIDCCode.objects.create(
            client=client, user=request.user, scopes=u' '.join(scopes),
            state=state, nonce=nonce, redirect_uri=redirect_uri,
            expired=start + datetime.timedelta(seconds=30),
            auth_time=datetime.datetime.fromtimestamp(last_auth['when'], utc),
            session_key=request.session.session_key)
        logger.info(u'sending code %s for scopes %s for service %s',
                    code.uuid, ' '.join(scopes),
                    client.name)
        params = {
            'code': unicode(code.uuid),
        }
        if state is not None:
            params['state'] = state
        response = redirect(request, redirect_uri, params=params, resolve=False)
    else:
        # FIXME: we should probably factorize this part with the token endpoint similar code
        need_access_token = 'token' in response_type.split()
        expires_in = 3600 * 8
        if need_access_token:
            access_token = models.OIDCAccessToken.objects.create(
                client=client,
                user=request.user,
                scopes=u' '.join(scopes),
                session_key=request.session.session_key,
                expired=start + datetime.timedelta(seconds=expires_in))
        acr = '0'
        if nonce is not None and last_auth.get('nonce') == nonce:
            acr = '1'
        id_token = utils.create_user_info(client, request.user, scopes, id_token=True)
        id_token.update({
            'iss': utils.get_issuer(request),
            'aud': client.client_id,
            'exp': timestamp_from_datetime(start + idtoken_duration(client)),
            'iat': timestamp_from_datetime(start),
            'auth_time': last_auth['when'],
            'acr': acr,
            'sid': utils.get_session_id(request, client),
        })
        if nonce is not None:
            id_token['nonce'] = nonce
        params = {
            'id_token': utils.make_idtoken(client, id_token),
        }
        if state is not None:
            params['state'] = state
        if need_access_token:
            params.update({
                'access_token': access_token.uuid,
                'token_type': 'Bearer',
                'expires_in': expires_in,
            })
        # query is transfered through the hashtag
        response = redirect(request, redirect_uri + '#%s' % urlencode(params), resolve=False)
    hooks.call_hooks('event', name='sso-success', idp='oidc', service=client, user=request.user)
    utils.add_oidc_session(request, client)
    return response
Exemplo n.º 23
0
 def get_context_data(self, **kwargs):
     form = self.get_form()
     hooks.call_hooks('manager_modify_form', self, form)
     kwargs['form'] = form
     ctx = super(BaseDetailView, self).get_context_data(**kwargs)
     return ctx
Exemplo n.º 24
0
 def get_form(self, form_class=None):
     form = super(ModelFormView, self).get_form(form_class=form_class)
     hooks.call_hooks('manager_modify_form', self, form)
     return form
Exemplo n.º 25
0
 def get_table(self, **kwargs):
     table = super(TableHookMixin, self).get_table(**kwargs)
     import copy
     table = copy.deepcopy(table)
     hooks.call_hooks('manager_modify_table', self, table)
     return table