core: allow filtering users by the groups they are in
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
ff24bc8cb8
commit
3e909ae6bb
|
@ -6,7 +6,7 @@ from django.db.models.query import QuerySet
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
from django.utils.http import urlencode
|
from django.utils.http import urlencode
|
||||||
from django.utils.translation import gettext as _
|
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 django_filters.filterset import FilterSet
|
||||||
from drf_spectacular.types import OpenApiTypes
|
from drf_spectacular.types import OpenApiTypes
|
||||||
from drf_spectacular.utils import OpenApiParameter, extend_schema, extend_schema_field
|
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")
|
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
|
# pylint: disable=unused-argument
|
||||||
def filter_attributes(self, queryset, name, value):
|
def filter_attributes(self, queryset, name, value):
|
||||||
"""Filter attributes by query args"""
|
"""Filter attributes by query args"""
|
||||||
|
@ -172,6 +182,8 @@ class UsersFilter(FilterSet):
|
||||||
"is_active",
|
"is_active",
|
||||||
"is_superuser",
|
"is_superuser",
|
||||||
"attributes",
|
"attributes",
|
||||||
|
"groups_by_name",
|
||||||
|
"groups_by_pk",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ class TestOAuthSource(TestCase):
|
||||||
data={
|
data={
|
||||||
"name": "foo",
|
"name": "foo",
|
||||||
"slug": "bar",
|
"slug": "bar",
|
||||||
"provider_type": "openid-connect",
|
"provider_type": "openidconnect",
|
||||||
"consumer_key": "foo",
|
"consumer_key": "foo",
|
||||||
"consumer_secret": "foo",
|
"consumer_secret": "foo",
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ func parseFilterForGroupSingle(req api.ApiCoreGroupsListRequest, f *ber.Packet)
|
||||||
case "cn":
|
case "cn":
|
||||||
return req.Name(vv)
|
return req.Name(vv)
|
||||||
case "member":
|
case "member":
|
||||||
|
case "memberOf":
|
||||||
userDN, err := goldap.ParseDN(vv)
|
userDN, err := goldap.ParseDN(vv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return req
|
return req
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package ldap
|
package ldap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
goldap "github.com/go-ldap/ldap/v3"
|
||||||
ber "github.com/nmcclain/asn1-ber"
|
ber "github.com/nmcclain/asn1-ber"
|
||||||
"github.com/nmcclain/ldap"
|
"github.com/nmcclain/ldap"
|
||||||
"goauthentik.io/api"
|
"goauthentik.io/api"
|
||||||
|
@ -45,6 +46,14 @@ func parseFilterForUserSingle(req api.ApiCoreUsersListRequest, f *ber.Packet) ap
|
||||||
return req.Name(vv)
|
return req.Name(vv)
|
||||||
case "mail":
|
case "mail":
|
||||||
return req.Email(vv)
|
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
|
// TODO: Support int
|
||||||
default:
|
default:
|
||||||
|
|
17
schema.yml
17
schema.yml
|
@ -2914,6 +2914,23 @@ paths:
|
||||||
name: email
|
name: email
|
||||||
schema:
|
schema:
|
||||||
type: string
|
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
|
- in: query
|
||||||
name: is_active
|
name: is_active
|
||||||
schema:
|
schema:
|
||||||
|
|
|
@ -36,9 +36,11 @@ export class OAuthSourceForm extends ModelForm<OAuthSource, string> {
|
||||||
@property()
|
@property()
|
||||||
set modelName(v: string | undefined) {
|
set modelName(v: string | undefined) {
|
||||||
this._modelName = v;
|
this._modelName = v;
|
||||||
new SourcesApi(DEFAULT_CONFIG).sourcesOauthSourceTypesList({
|
new SourcesApi(DEFAULT_CONFIG)
|
||||||
|
.sourcesOauthSourceTypesList({
|
||||||
name: v?.replace("oauthsource", ""),
|
name: v?.replace("oauthsource", ""),
|
||||||
}).then((type) => {
|
})
|
||||||
|
.then((type) => {
|
||||||
this.providerType = type[0];
|
this.providerType = type[0];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -85,7 +87,10 @@ export class OAuthSourceForm extends ModelForm<OAuthSource, string> {
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value="${first(this.instance?.authorizationUrl, this.providerType.authorizationUrl)}"
|
value="${first(
|
||||||
|
this.instance?.authorizationUrl,
|
||||||
|
this.providerType.authorizationUrl,
|
||||||
|
)}"
|
||||||
class="pf-c-form-control"
|
class="pf-c-form-control"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
@ -100,7 +105,10 @@ export class OAuthSourceForm extends ModelForm<OAuthSource, string> {
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value="${first(this.instance?.accessTokenUrl, this.providerType.accessTokenUrl)}"
|
value="${first(
|
||||||
|
this.instance?.accessTokenUrl,
|
||||||
|
this.providerType.accessTokenUrl,
|
||||||
|
)}"
|
||||||
class="pf-c-form-control"
|
class="pf-c-form-control"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
|
|
Reference in New Issue