web/admin: filter out service accounts by default
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
a335ca0895
commit
0d370ef0a9
8
Makefile
8
Makefile
|
@ -22,7 +22,7 @@ lint:
|
|||
bandit -r authentik tests lifecycle -x node_modules
|
||||
pylint authentik tests lifecycle
|
||||
|
||||
gen: coverage
|
||||
gen:
|
||||
./manage.py generate_swagger -o swagger.yaml -f yaml
|
||||
|
||||
local-stack:
|
||||
|
@ -31,7 +31,5 @@ local-stack:
|
|||
docker-compose up -d
|
||||
docker-compose run --rm server migrate
|
||||
|
||||
build-static:
|
||||
docker-compose -f scripts/ci.docker-compose.yml up -d
|
||||
docker build -t beryju/authentik-static -f static.Dockerfile --network=scripts_default .
|
||||
docker-compose -f scripts/ci.docker-compose.yml down -v
|
||||
run:
|
||||
go run -v cmd/server/main.go
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
"""User API Views"""
|
||||
from json import loads
|
||||
|
||||
from django.http.response import Http404
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.http import urlencode
|
||||
from django_filters.filters import CharFilter
|
||||
from django_filters.filterset import FilterSet
|
||||
from drf_yasg.utils import swagger_auto_schema, swagger_serializer_method
|
||||
from guardian.utils import get_anonymous_user
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.fields import CharField, JSONField, SerializerMethodField
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.serializers import BooleanField, ModelSerializer
|
||||
from rest_framework.serializers import BooleanField, ModelSerializer, ValidationError
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from authentik.admin.api.metrics import CoordinateSerializer, get_events_per_1h
|
||||
|
@ -84,13 +88,42 @@ class UserMetricsSerializer(PassiveSerializer):
|
|||
)
|
||||
|
||||
|
||||
class UsersFilter(FilterSet):
|
||||
"""Filter for users"""
|
||||
|
||||
attributes = CharFilter(
|
||||
field_name="attributes",
|
||||
lookup_expr="",
|
||||
label="Attributes",
|
||||
method="filter_attributes",
|
||||
)
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def filter_attributes(self, queryset, name, value):
|
||||
"""Filter attributes by query args"""
|
||||
try:
|
||||
value = loads(value)
|
||||
except ValueError:
|
||||
raise ValidationError(detail="filter: failed to parse JSON")
|
||||
if not isinstance(value, dict):
|
||||
raise ValidationError(detail="filter: value must be key:value mapping")
|
||||
qs = {}
|
||||
for key, _value in value.items():
|
||||
qs[f"attributes__{key}"] = _value
|
||||
return queryset.filter(**qs)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ["username", "name", "is_active", "attributes"]
|
||||
|
||||
|
||||
class UserViewSet(ModelViewSet):
|
||||
"""User Viewset"""
|
||||
|
||||
queryset = User.objects.none()
|
||||
serializer_class = UserSerializer
|
||||
search_fields = ["username", "name", "is_active"]
|
||||
filterset_fields = ["username", "name", "is_active"]
|
||||
filterset_class = UsersFilter
|
||||
|
||||
def get_queryset(self):
|
||||
return User.objects.all().exclude(pk=get_anonymous_user().pk)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package web
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
)
|
||||
|
@ -9,5 +10,11 @@ func (ws *WebServer) configureProxy() {
|
|||
// Reverse proxy to the application server
|
||||
u, _ := url.Parse("http://localhost:8000")
|
||||
rp := httputil.NewSingleHostReverseProxy(u)
|
||||
rp.ErrorHandler = ws.proxyErrorHandler
|
||||
ws.m.PathPrefix("/").Handler(rp)
|
||||
}
|
||||
|
||||
func (ws *WebServer) proxyErrorHandler(rw http.ResponseWriter, req *http.Request, err error) {
|
||||
ws.log.WithError(err).Warning("proxy error")
|
||||
rw.WriteHeader(http.StatusBadGateway)
|
||||
}
|
||||
|
|
|
@ -1994,6 +1994,11 @@ paths:
|
|||
description: ''
|
||||
required: false
|
||||
type: string
|
||||
- name: attributes
|
||||
in: query
|
||||
description: ''
|
||||
required: false
|
||||
type: string
|
||||
- name: ordering
|
||||
in: query
|
||||
description: Which field to use when ordering the results.
|
||||
|
|
|
@ -56,7 +56,7 @@ export class PlexSourceForm extends Form<PlexSource> {
|
|||
};
|
||||
|
||||
async doAuth(): Promise<void> {
|
||||
const authInfo = await PlexAPIClient.getPin(this.source?.clientId);
|
||||
const authInfo = await PlexAPIClient.getPin(this.source?.clientId || "");
|
||||
const authWindow = popupCenterScreen(authInfo.authUrl, "plex auth", 550, 700);
|
||||
PlexAPIClient.pinPoll(this.source?.clientId || "", authInfo.pin.id).then(token => {
|
||||
authWindow?.close();
|
||||
|
|
|
@ -35,12 +35,18 @@ export class UserListPage extends TablePage<User> {
|
|||
@property()
|
||||
order = "last_login";
|
||||
|
||||
@property({ type: Boolean })
|
||||
hideServiceAccounts = true;
|
||||
|
||||
apiEndpoint(page: number): Promise<AKResponse<User>> {
|
||||
return new CoreApi(DEFAULT_CONFIG).coreUsersList({
|
||||
ordering: this.order,
|
||||
page: page,
|
||||
pageSize: PAGE_SIZE,
|
||||
search: this.search || "",
|
||||
attributes: this.hideServiceAccounts ? JSON.stringify({
|
||||
"goauthentik.io/user/service-account__isnull": "true"
|
||||
}) : undefined
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -163,4 +169,29 @@ export class UserListPage extends TablePage<User> {
|
|||
`;
|
||||
}
|
||||
|
||||
renderToolbarAfter(): TemplateResult {
|
||||
return html`
|
||||
<div class="pf-c-toolbar__group pf-m-filter-group">
|
||||
<div class="pf-c-toolbar__item pf-m-search-filter">
|
||||
<div class="pf-c-input-group">
|
||||
<div class="pf-c-check">
|
||||
<input class="pf-c-check__input"
|
||||
type="checkbox"
|
||||
id="hide-service-accounts"
|
||||
name="hide-service-accounts"
|
||||
?checked=${this.hideServiceAccounts}
|
||||
@change=${() => {
|
||||
this.hideServiceAccounts = !this.hideServiceAccounts;
|
||||
this.page = 1;
|
||||
this.fetch();
|
||||
}} />
|
||||
<label class="pf-c-check__label" for="hide-service-accounts">
|
||||
${t`Hide service-accounts`}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Reference in New Issue