core: allow filtering users by the groups they are in

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-08-21 16:23:07 +02:00
parent ff24bc8cb8
commit 3e909ae6bb
6 changed files with 57 additions and 10 deletions

View File

@ -6,7 +6,7 @@ from django.db.models.query import QuerySet
from django.urls import reverse_lazy
from django.utils.http import urlencode
from django.utils.translation import gettext as _
from django_filters.filters import BooleanFilter, CharFilter
from django_filters.filters import BooleanFilter, CharFilter, ModelMultipleChoiceFilter
from django_filters.filterset import FilterSet
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import OpenApiParameter, extend_schema, extend_schema_field
@ -149,6 +149,16 @@ class UsersFilter(FilterSet):
is_superuser = BooleanFilter(field_name="ak_groups", lookup_expr="is_superuser")
groups_by_name = ModelMultipleChoiceFilter(
field_name="ak_groups__username",
to_field_name="username",
queryset=Group.objects.all(),
)
groups_by_pk = ModelMultipleChoiceFilter(
field_name="ak_groups",
queryset=Group.objects.all(),
)
# pylint: disable=unused-argument
def filter_attributes(self, queryset, name, value):
"""Filter attributes by query args"""
@ -172,6 +182,8 @@ class UsersFilter(FilterSet):
"is_active",
"is_superuser",
"attributes",
"groups_by_name",
"groups_by_pk",
]

View File

@ -37,7 +37,7 @@ class TestOAuthSource(TestCase):
data={
"name": "foo",
"slug": "bar",
"provider_type": "openid-connect",
"provider_type": "openidconnect",
"consumer_key": "foo",
"consumer_secret": "foo",
}

View File

@ -42,6 +42,7 @@ func parseFilterForGroupSingle(req api.ApiCoreGroupsListRequest, f *ber.Packet)
case "cn":
return req.Name(vv)
case "member":
case "memberOf":
userDN, err := goldap.ParseDN(vv)
if err != nil {
return req

View File

@ -1,6 +1,7 @@
package ldap
import (
goldap "github.com/go-ldap/ldap/v3"
ber "github.com/nmcclain/asn1-ber"
"github.com/nmcclain/ldap"
"goauthentik.io/api"
@ -45,6 +46,14 @@ func parseFilterForUserSingle(req api.ApiCoreUsersListRequest, f *ber.Packet) ap
return req.Name(vv)
case "mail":
return req.Email(vv)
case "member":
case "memberOf":
groupDN, err := goldap.ParseDN(vv)
if err != nil {
return req
}
name := groupDN.RDNs[0].Attributes[0].Value
return req.GroupsByName([]string{name})
}
// TODO: Support int
default:

View File

@ -2914,6 +2914,23 @@ paths:
name: email
schema:
type: string
- in: query
name: groups_by_name
schema:
type: array
items:
type: string
explode: true
style: form
- in: query
name: groups_by_pk
schema:
type: array
items:
type: string
format: uuid
explode: true
style: form
- in: query
name: is_active
schema:

View File

@ -36,13 +36,15 @@ export class OAuthSourceForm extends ModelForm<OAuthSource, string> {
@property()
set modelName(v: string | undefined) {
this._modelName = v;
new SourcesApi(DEFAULT_CONFIG).sourcesOauthSourceTypesList({
name: v?.replace("oauthsource", ""),
}).then((type) => {
this.providerType = type[0];
});
new SourcesApi(DEFAULT_CONFIG)
.sourcesOauthSourceTypesList({
name: v?.replace("oauthsource", ""),
})
.then((type) => {
this.providerType = type[0];
});
}
get modelName(): string|undefined {
get modelName(): string | undefined {
return this._modelName;
}
@ -85,7 +87,10 @@ export class OAuthSourceForm extends ModelForm<OAuthSource, string> {
>
<input
type="text"
value="${first(this.instance?.authorizationUrl, this.providerType.authorizationUrl)}"
value="${first(
this.instance?.authorizationUrl,
this.providerType.authorizationUrl,
)}"
class="pf-c-form-control"
required
/>
@ -100,7 +105,10 @@ export class OAuthSourceForm extends ModelForm<OAuthSource, string> {
>
<input
type="text"
value="${first(this.instance?.accessTokenUrl, this.providerType.accessTokenUrl)}"
value="${first(
this.instance?.accessTokenUrl,
this.providerType.accessTokenUrl,
)}"
class="pf-c-form-control"
required
/>