the rest of the owl
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
@ -1,12 +0,0 @@
|
||||
"""authentik administration metrics"""
|
||||
|
||||
from rest_framework.fields import IntegerField
|
||||
|
||||
from authentik.core.api.utils import PassiveSerializer
|
||||
|
||||
|
||||
class CoordinateSerializer(PassiveSerializer):
|
||||
"""Coordinates for diagrams"""
|
||||
|
||||
x_cord = IntegerField(read_only=True)
|
||||
y_cord = IntegerField(read_only=True)
|
||||
@ -1,12 +1,11 @@
|
||||
"""Events API Views"""
|
||||
|
||||
from datetime import timedelta
|
||||
from json import loads
|
||||
|
||||
import django_filters
|
||||
from django.db.models import Count, QuerySet
|
||||
from django.db.models.fields.json import KeyTextTransform, KeyTransform
|
||||
from django.db.models.functions import ExtractDay, TruncDate
|
||||
from django.db.models.functions import TruncDate
|
||||
from django.db.models.query_utils import Q
|
||||
from django.utils.timezone import now
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
@ -18,7 +17,6 @@ from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from authentik.admin.api.metrics import CoordinateSerializer
|
||||
from authentik.core.api.object_types import TypeCreateSerializer
|
||||
from authentik.core.api.utils import ModelSerializer, PassiveSerializer
|
||||
from authentik.events.models import Event, EventAction
|
||||
@ -199,39 +197,6 @@ class EventViewSet(ModelViewSet):
|
||||
.order_by("-day", "action")
|
||||
)
|
||||
|
||||
@extend_schema(
|
||||
responses={200: CoordinateSerializer(many=True)},
|
||||
filters=[],
|
||||
parameters=[
|
||||
OpenApiParameter(
|
||||
"action",
|
||||
type=OpenApiTypes.STR,
|
||||
location=OpenApiParameter.QUERY,
|
||||
required=False,
|
||||
),
|
||||
OpenApiParameter(
|
||||
"query",
|
||||
type=OpenApiTypes.STR,
|
||||
location=OpenApiParameter.QUERY,
|
||||
required=False,
|
||||
),
|
||||
],
|
||||
)
|
||||
@action(detail=False, methods=["GET"], pagination_class=None)
|
||||
def per_month(self, request: Request):
|
||||
"""Get the count of events per month"""
|
||||
filtered_action = request.query_params.get("action", EventAction.LOGIN)
|
||||
try:
|
||||
query = loads(request.query_params.get("query", "{}"))
|
||||
except ValueError:
|
||||
return Response(status=400)
|
||||
return Response(
|
||||
get_objects_for_user(request.user, "authentik_events.view_event")
|
||||
.filter(action=filtered_action)
|
||||
.filter(**query)
|
||||
.get_events_per(timedelta(weeks=4), ExtractDay, 30)
|
||||
)
|
||||
|
||||
@extend_schema(responses={200: TypeCreateSerializer(many=True)})
|
||||
@action(detail=False, pagination_class=None, filter_backends=[])
|
||||
def actions(self, request: Request) -> Response:
|
||||
|
||||
51
schema.yml
51
schema.yml
@ -7337,44 +7337,6 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/events/events/per_month/:
|
||||
get:
|
||||
operationId: events_events_per_month_list
|
||||
description: Get the count of events per month
|
||||
parameters:
|
||||
- in: query
|
||||
name: action
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: query
|
||||
schema:
|
||||
type: string
|
||||
tags:
|
||||
- events
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Coordinate'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/events/events/top_per_user/:
|
||||
get:
|
||||
operationId: events_events_top_per_user_list
|
||||
@ -43576,19 +43538,6 @@ components:
|
||||
- sidebar_left
|
||||
- sidebar_right
|
||||
type: string
|
||||
Coordinate:
|
||||
type: object
|
||||
description: Coordinates for diagrams
|
||||
properties:
|
||||
x_cord:
|
||||
type: integer
|
||||
readOnly: true
|
||||
y_cord:
|
||||
type: integer
|
||||
readOnly: true
|
||||
required:
|
||||
- x_cord
|
||||
- y_cord
|
||||
CountryCodeEnum:
|
||||
enum:
|
||||
- AF
|
||||
|
||||
@ -13,7 +13,7 @@ import PFList from "@patternfly/patternfly/components/List/list.css";
|
||||
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
||||
|
||||
import { EventActions } from "@goauthentik/api";
|
||||
import { EventActions, EventsEventsVolumeListRequest } from "@goauthentik/api";
|
||||
|
||||
@customElement("ak-admin-dashboard-users")
|
||||
export class DashboardUserPage extends AKElement {
|
||||
@ -46,9 +46,9 @@ export class DashboardUserPage extends AKElement {
|
||||
<ak-aggregate-card header=${msg("Users created per day in the last month")}>
|
||||
<ak-charts-admin-model-per-day
|
||||
.query=${{
|
||||
context__model__app: "authentik_core",
|
||||
context__model__model_name: "user",
|
||||
}}
|
||||
contextModelApp: "authentik_core",
|
||||
contextModelName: "user",
|
||||
} as EventsEventsVolumeListRequest}
|
||||
label=${msg("Users created")}
|
||||
>
|
||||
</ak-charts-admin-model-per-day>
|
||||
|
||||
@ -5,10 +5,16 @@ import { ChartData, Tick } from "chart.js";
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
import { Coordinate, EventActions, EventsApi } from "@goauthentik/api";
|
||||
import {
|
||||
Coordinate,
|
||||
EventActions,
|
||||
EventVolume,
|
||||
EventsApi,
|
||||
EventsEventsVolumeListRequest,
|
||||
} from "@goauthentik/api";
|
||||
|
||||
@customElement("ak-charts-admin-model-per-day")
|
||||
export class AdminModelPerDay extends AKChart<Coordinate[]> {
|
||||
export class AdminModelPerDay extends AKChart<EventVolume[]> {
|
||||
@property()
|
||||
action: EventActions = EventActions.ModelCreated;
|
||||
|
||||
@ -16,39 +22,29 @@ export class AdminModelPerDay extends AKChart<Coordinate[]> {
|
||||
label?: string;
|
||||
|
||||
@property({ attribute: false })
|
||||
query?: { [key: string]: unknown } | undefined;
|
||||
query?: EventsEventsVolumeListRequest;
|
||||
|
||||
async apiRequest(): Promise<Coordinate[]> {
|
||||
return new EventsApi(DEFAULT_CONFIG).eventsEventsPerMonthList({
|
||||
async apiRequest(): Promise<EventVolume[]> {
|
||||
return new EventsApi(DEFAULT_CONFIG).eventsEventsVolumeList({
|
||||
action: this.action,
|
||||
query: JSON.stringify(this.query || {}),
|
||||
...this.query,
|
||||
});
|
||||
}
|
||||
|
||||
timeTickCallback(tickValue: string | number, index: number, ticks: Tick[]): string {
|
||||
const valueStamp = ticks[index];
|
||||
const delta = Date.now() - valueStamp.value;
|
||||
const ago = Math.round(delta / 1000 / 3600 / 24);
|
||||
return msg(str`${ago} days ago`);
|
||||
}
|
||||
|
||||
getChartData(data: Coordinate[]): ChartData {
|
||||
return {
|
||||
datasets: [
|
||||
getChartData(data: EventVolume[]): ChartData {
|
||||
return this.eventVolume(
|
||||
data,
|
||||
new Map([
|
||||
[
|
||||
this.action,
|
||||
{
|
||||
label: this.label || msg("Objects created"),
|
||||
backgroundColor: "rgba(189, 229, 184, .5)",
|
||||
spanGaps: true,
|
||||
data:
|
||||
data.map((cord) => {
|
||||
return {
|
||||
x: cord.xCord || 0,
|
||||
y: cord.yCord || 0,
|
||||
};
|
||||
}) || [],
|
||||
},
|
||||
],
|
||||
};
|
||||
]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ export class EventVolumeChart extends AKChart<EventVolume[]> {
|
||||
apiRequest(): Promise<EventVolume[]> {
|
||||
return new EventsApi(DEFAULT_CONFIG).eventsEventsVolumeList({
|
||||
historyDays: 14,
|
||||
...this._query
|
||||
...this._query,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user