*: add clear param to file upload API to delete stored file and reset field
closes #949 Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
277c2f4aad
commit
f5dbdbd48b
|
@ -11,7 +11,13 @@ from drf_spectacular.utils import (
|
|||
inline_serializer,
|
||||
)
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.fields import CharField, FileField, IntegerField, ReadOnlyField
|
||||
from rest_framework.fields import (
|
||||
BooleanField,
|
||||
CharField,
|
||||
FileField,
|
||||
IntegerField,
|
||||
ReadOnlyField,
|
||||
)
|
||||
from rest_framework.parsers import MultiPartParser
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
|
@ -173,7 +179,11 @@ class ApplicationViewSet(ModelViewSet):
|
|||
@extend_schema(
|
||||
request={
|
||||
"multipart/form-data": inline_serializer(
|
||||
"SetIcon", fields={"file": FileField()}
|
||||
"SetIcon",
|
||||
fields={
|
||||
"file": FileField(required=False),
|
||||
"clear": BooleanField(default=False),
|
||||
},
|
||||
)
|
||||
},
|
||||
responses={
|
||||
|
@ -193,11 +203,16 @@ class ApplicationViewSet(ModelViewSet):
|
|||
"""Set application icon"""
|
||||
app: Application = self.get_object()
|
||||
icon = request.FILES.get("file", None)
|
||||
if not icon:
|
||||
return HttpResponseBadRequest()
|
||||
app.meta_icon = icon
|
||||
app.save()
|
||||
return Response({})
|
||||
clear = request.data.get("clear", False)
|
||||
if clear:
|
||||
# .delete() saves the model by default
|
||||
app.meta_icon.delete()
|
||||
return Response({})
|
||||
if icon:
|
||||
app.meta_icon = icon
|
||||
app.save()
|
||||
return Response({})
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
@permission_required("authentik_core.change_application")
|
||||
@extend_schema(
|
||||
|
|
|
@ -10,7 +10,7 @@ from drf_spectacular.types import OpenApiTypes
|
|||
from drf_spectacular.utils import OpenApiResponse, extend_schema, inline_serializer
|
||||
from guardian.shortcuts import get_objects_for_user
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.fields import FileField, ReadOnlyField
|
||||
from rest_framework.fields import BooleanField, FileField, ReadOnlyField
|
||||
from rest_framework.parsers import MultiPartParser
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
|
@ -269,7 +269,11 @@ class FlowViewSet(ModelViewSet):
|
|||
@extend_schema(
|
||||
request={
|
||||
"multipart/form-data": inline_serializer(
|
||||
"SetIcon", fields={"file": FileField()}
|
||||
"SetIcon",
|
||||
fields={
|
||||
"file": FileField(required=False),
|
||||
"clear": BooleanField(default=False),
|
||||
},
|
||||
)
|
||||
},
|
||||
responses={
|
||||
|
@ -288,12 +292,17 @@ class FlowViewSet(ModelViewSet):
|
|||
def set_background(self, request: Request, slug: str):
|
||||
"""Set Flow background"""
|
||||
flow: Flow = self.get_object()
|
||||
icon = request.FILES.get("file", None)
|
||||
if not icon:
|
||||
return HttpResponseBadRequest()
|
||||
flow.background = icon
|
||||
flow.save()
|
||||
return Response({})
|
||||
background = request.FILES.get("file", None)
|
||||
clear = request.data.get("clear", False)
|
||||
if clear:
|
||||
# .delete() saves the model by default
|
||||
flow.background.delete()
|
||||
return Response({})
|
||||
if background:
|
||||
flow.background = background
|
||||
flow.save()
|
||||
return Response({})
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
@permission_required("authentik_core.change_application")
|
||||
@extend_schema(
|
||||
|
|
|
@ -1474,7 +1474,6 @@ paths:
|
|||
multipart/form-data:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SetIconRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
- cookieAuth: []
|
||||
|
@ -4519,7 +4518,6 @@ paths:
|
|||
multipart/form-data:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SetIconRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
- cookieAuth: []
|
||||
|
@ -4612,7 +4610,6 @@ paths:
|
|||
multipart/form-data:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SetIconRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
- cookieAuth: []
|
||||
|
@ -24890,8 +24887,9 @@ components:
|
|||
file:
|
||||
type: string
|
||||
format: binary
|
||||
required:
|
||||
- file
|
||||
clear:
|
||||
type: boolean
|
||||
default: false
|
||||
SetIconURLRequest:
|
||||
type: object
|
||||
properties:
|
||||
|
|
|
@ -593,6 +593,10 @@ msgstr "Clear Flow cache"
|
|||
msgid "Clear Policy cache"
|
||||
msgstr "Clear Policy cache"
|
||||
|
||||
#: src/pages/flows/FlowForm.ts
|
||||
msgid "Clear background image"
|
||||
msgstr "Clear background image"
|
||||
|
||||
#: src/pages/flows/FlowListPage.ts
|
||||
#: src/pages/flows/FlowListPage.ts
|
||||
#: src/pages/policies/PolicyListPage.ts
|
||||
|
@ -600,6 +604,10 @@ msgstr "Clear Policy cache"
|
|||
msgid "Clear cache"
|
||||
msgstr "Clear cache"
|
||||
|
||||
#: src/pages/applications/ApplicationForm.ts
|
||||
msgid "Clear icon"
|
||||
msgstr "Clear icon"
|
||||
|
||||
#: src/elements/forms/HorizontalFormElement.ts
|
||||
msgid "Click to change value"
|
||||
msgstr "Click to change value"
|
||||
|
@ -948,6 +956,7 @@ msgstr "Created {0}"
|
|||
msgid "Creation Date"
|
||||
msgstr "Creation Date"
|
||||
|
||||
#: src/pages/applications/ApplicationForm.ts
|
||||
#: src/pages/flows/FlowForm.ts
|
||||
msgid "Currently set to:"
|
||||
msgstr "Currently set to:"
|
||||
|
@ -1040,6 +1049,14 @@ msgstr "Delete Session"
|
|||
msgid "Delete account"
|
||||
msgstr "Delete account"
|
||||
|
||||
#: src/pages/flows/FlowForm.ts
|
||||
msgid "Delete currently set background image."
|
||||
msgstr "Delete currently set background image."
|
||||
|
||||
#: src/pages/applications/ApplicationForm.ts
|
||||
msgid "Delete currently set icon."
|
||||
msgstr "Delete currently set icon."
|
||||
|
||||
#: src/pages/sources/saml/SAMLSourceForm.ts
|
||||
msgid "Delete temporary users after"
|
||||
msgstr "Delete temporary users after"
|
||||
|
@ -1744,6 +1761,7 @@ msgstr "IP"
|
|||
msgid "IP Reputation"
|
||||
msgstr "IP Reputation"
|
||||
|
||||
#: src/pages/applications/ApplicationForm.ts
|
||||
#: src/pages/applications/ApplicationForm.ts
|
||||
msgid "Icon"
|
||||
msgstr "Icon"
|
||||
|
|
|
@ -587,6 +587,10 @@ msgstr ""
|
|||
msgid "Clear Policy cache"
|
||||
msgstr ""
|
||||
|
||||
#:
|
||||
msgid "Clear background image"
|
||||
msgstr ""
|
||||
|
||||
#:
|
||||
#:
|
||||
#:
|
||||
|
@ -594,6 +598,10 @@ msgstr ""
|
|||
msgid "Clear cache"
|
||||
msgstr ""
|
||||
|
||||
#:
|
||||
msgid "Clear icon"
|
||||
msgstr ""
|
||||
|
||||
#:
|
||||
msgid "Click to change value"
|
||||
msgstr ""
|
||||
|
@ -942,6 +950,7 @@ msgstr ""
|
|||
msgid "Creation Date"
|
||||
msgstr ""
|
||||
|
||||
#:
|
||||
#:
|
||||
msgid "Currently set to:"
|
||||
msgstr ""
|
||||
|
@ -1034,6 +1043,14 @@ msgstr ""
|
|||
msgid "Delete account"
|
||||
msgstr ""
|
||||
|
||||
#:
|
||||
msgid "Delete currently set background image."
|
||||
msgstr ""
|
||||
|
||||
#:
|
||||
msgid "Delete currently set icon."
|
||||
msgstr ""
|
||||
|
||||
#:
|
||||
msgid "Delete temporary users after"
|
||||
msgstr ""
|
||||
|
@ -1736,6 +1753,7 @@ msgstr ""
|
|||
msgid "IP Reputation"
|
||||
msgstr ""
|
||||
|
||||
#:
|
||||
#:
|
||||
msgid "Icon"
|
||||
msgstr ""
|
||||
|
|
|
@ -27,6 +27,9 @@ export class ApplicationForm extends ModelForm<Application, string> {
|
|||
@property({ attribute: false })
|
||||
provider?: number;
|
||||
|
||||
@property({ type: Boolean })
|
||||
clearIcon = false;
|
||||
|
||||
getSuccessMessage(): string {
|
||||
if (this.instance) {
|
||||
return t`Successfully updated application.`;
|
||||
|
@ -54,11 +57,12 @@ export class ApplicationForm extends ModelForm<Application, string> {
|
|||
return config().then((c) => {
|
||||
if (c.capabilities.includes(CapabilitiesEnum.SaveMedia)) {
|
||||
const icon = this.getFormFile();
|
||||
if (icon) {
|
||||
if (icon || this.clearIcon) {
|
||||
return writeOp.then(app => {
|
||||
return new CoreApi(DEFAULT_CONFIG).coreApplicationsSetIconCreate({
|
||||
slug: app.slug,
|
||||
file: icon
|
||||
file: icon,
|
||||
clear: this.clearIcon,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -186,7 +190,21 @@ export class ApplicationForm extends ModelForm<Application, string> {
|
|||
${this.instance?.metaIcon ? html`
|
||||
<p class="pf-c-form__helper-text">${t`Currently set to:`} ${this.instance?.metaIcon}</p>
|
||||
`: html``}
|
||||
</ak-form-element-horizontal>`;
|
||||
</ak-form-element-horizontal>
|
||||
${this.instance?.metaIcon ? html`
|
||||
<ak-form-element-horizontal>
|
||||
<div class="pf-c-check">
|
||||
<input type="checkbox" class="pf-c-check__input" @change=${(ev: Event) => {
|
||||
const target = ev.target as HTMLInputElement;
|
||||
this.clearIcon = target.checked;
|
||||
}}>
|
||||
<label class="pf-c-check__label">
|
||||
${t`Clear icon`}
|
||||
</label>
|
||||
</div>
|
||||
<p class="pf-c-form__helper-text">${t`Delete currently set icon.`}</p>
|
||||
</ak-form-element-horizontal>
|
||||
`: html``}`;
|
||||
}
|
||||
return html`<ak-form-element-horizontal
|
||||
label=${t`Icon`}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Flow, FlowDesignationEnum, PolicyEngineMode, FlowsApi, CapabilitiesEnum } from "authentik-api";
|
||||
import { t } from "@lingui/macro";
|
||||
import { customElement } from "lit-element";
|
||||
import { customElement, property } from "lit-element";
|
||||
import { html, TemplateResult } from "lit-html";
|
||||
import { config, DEFAULT_CONFIG } from "../../api/Config";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
|
@ -26,6 +26,9 @@ export class FlowForm extends ModelForm<Flow, string> {
|
|||
}
|
||||
}
|
||||
|
||||
@property({ type: Boolean })
|
||||
clearBackground = false;
|
||||
|
||||
send = (data: Flow): Promise<void | Flow> => {
|
||||
let writeOp: Promise<Flow>;
|
||||
if (this.instance) {
|
||||
|
@ -41,11 +44,12 @@ export class FlowForm extends ModelForm<Flow, string> {
|
|||
return config().then((c) => {
|
||||
if (c.capabilities.includes(CapabilitiesEnum.SaveMedia)) {
|
||||
const icon = this.getFormFile();
|
||||
if (icon) {
|
||||
if (icon || this.clearBackground) {
|
||||
return writeOp.then(app => {
|
||||
return new FlowsApi(DEFAULT_CONFIG).flowsInstancesSetBackgroundCreate({
|
||||
slug: app.slug,
|
||||
file: icon
|
||||
file: icon,
|
||||
clear: this.clearBackground,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -143,7 +147,21 @@ export class FlowForm extends ModelForm<Flow, string> {
|
|||
<p class="pf-c-form__helper-text">${t`Currently set to:`} ${this.instance?.background}</p>
|
||||
`: html``}
|
||||
<p class="pf-c-form__helper-text">${t`Background shown during execution.`}</p>
|
||||
</ak-form-element-horizontal>`;
|
||||
</ak-form-element-horizontal>
|
||||
${this.instance?.background ? html`
|
||||
<ak-form-element-horizontal>
|
||||
<div class="pf-c-check">
|
||||
<input type="checkbox" class="pf-c-check__input" @change=${(ev: Event) => {
|
||||
const target = ev.target as HTMLInputElement;
|
||||
this.clearBackground = target.checked;
|
||||
}}>
|
||||
<label class="pf-c-check__label">
|
||||
${t`Clear background image`}
|
||||
</label>
|
||||
</div>
|
||||
<p class="pf-c-form__helper-text">${t`Delete currently set background image.`}</p>
|
||||
</ak-form-element-horizontal>
|
||||
`: html``}`;
|
||||
}
|
||||
return html`<ak-form-element-horizontal
|
||||
label=${t`Background`}
|
||||
|
|
Reference in a new issue