providers/rac: fix property mapping without enterprise (#8144)

* make rac blueprint only run when enterprise is active

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* make rac api same as other mappings

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* automatically scale size sent by device pixel ratio

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* actually always allow creation of rac mappings

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix missing application in flow context

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix wizard showing enterprise warning when license is installed

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* cleanup

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L 2024-01-14 21:21:06 +01:00 committed by GitHub
parent 7c116acf0f
commit 85f1584844
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 43 additions and 11 deletions

View file

@ -35,7 +35,7 @@ from authentik.core.models import (
Source,
UserSourceConnection,
)
from authentik.enterprise.models import LicenseUsage
from authentik.enterprise.models import LicenseKey, LicenseUsage
from authentik.events.utils import cleanse_dict
from authentik.flows.models import FlowToken, Stage
from authentik.lib.models import SerializerModel
@ -108,12 +108,16 @@ class Importer:
self.__pk_map: dict[Any, Model] = {}
self._import = blueprint
self.logger = get_logger()
ctx = {}
ctx = self.default_context()
always_merger.merge(ctx, self._import.context)
if context:
always_merger.merge(ctx, context)
self._import.context = ctx
def default_context(self):
"""Default context"""
return {"goauthentik.io/enterprise/licensed": LicenseKey.get_total().is_valid()}
@staticmethod
def from_string(yaml_input: str, context: dict | None = None) -> "Importer":
"""Parse YAML string and create blueprint importer from it"""

View file

@ -1,15 +1,18 @@
"""RAC Provider API Views"""
from django_filters.filters import AllValuesMultipleFilter
from django_filters.filterset import FilterSet
from drf_spectacular.types import OpenApiTypes
from drf_spectacular.utils import extend_schema_field
from rest_framework.fields import CharField
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.propertymappings import PropertyMappingSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import JSONDictField
from authentik.enterprise.api import EnterpriseRequiredMixin
from authentik.enterprise.providers.rac.models import RACPropertyMapping
class RACPropertyMappingSerializer(EnterpriseRequiredMixin, PropertyMappingSerializer):
class RACPropertyMappingSerializer(PropertyMappingSerializer):
"""RACPropertyMapping Serializer"""
static_settings = JSONDictField()
@ -26,6 +29,16 @@ class RACPropertyMappingSerializer(EnterpriseRequiredMixin, PropertyMappingSeria
fields = PropertyMappingSerializer.Meta.fields + ["static_settings"]
class RACPropertyMappingFilter(FilterSet):
"""Filter for RACPropertyMapping"""
managed = extend_schema_field(OpenApiTypes.STR)(AllValuesMultipleFilter(field_name="managed"))
class Meta:
model = RACPropertyMapping
fields = ["name", "managed"]
class RACPropertyMappingViewSet(UsedByMixin, ModelViewSet):
"""RACPropertyMapping Viewset"""
@ -33,4 +46,4 @@ class RACPropertyMappingViewSet(UsedByMixin, ModelViewSet):
serializer_class = RACPropertyMappingSerializer
search_fields = ["name"]
ordering = ["name"]
filterset_fields = ["name", "managed"]
filterset_class = RACPropertyMappingFilter

View file

@ -15,7 +15,7 @@ from authentik.events.models import Event, EventAction
from authentik.flows.challenge import RedirectChallenge
from authentik.flows.exceptions import FlowNonApplicableException
from authentik.flows.models import in_memory_stage
from authentik.flows.planner import FlowPlanner
from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, FlowPlanner
from authentik.flows.stage import RedirectStage
from authentik.flows.views.executor import SESSION_KEY_PLAN
from authentik.lib.utils.time import timedelta_from_string
@ -39,7 +39,12 @@ class RACStartView(EnterprisePolicyAccessView):
planner = FlowPlanner(self.provider.authorization_flow)
planner.allow_empty_flows = True
try:
plan = planner.plan(self.request)
plan = planner.plan(
self.request,
{
PLAN_CONTEXT_APPLICATION: self.application,
},
)
except FlowNonApplicableException:
raise Http404
plan.insert_stage(

View file

@ -13961,7 +13961,11 @@ paths:
- in: query
name: managed
schema:
type: string
type: array
items:
type: string
explode: true
style: form
- in: query
name: name
schema:

View file

@ -5,6 +5,7 @@ import "@goauthentik/admin/property-mappings/PropertyMappingSAMLForm";
import "@goauthentik/admin/property-mappings/PropertyMappingScopeForm";
import "@goauthentik/admin/property-mappings/PropertyMappingTestForm";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import "@goauthentik/elements/Alert";
import { AKElement } from "@goauthentik/elements/Base";
import "@goauthentik/elements/forms/ProxyForm";
import "@goauthentik/elements/wizard/FormWizardPage";
@ -63,7 +64,7 @@ export class InitialPropertyMappingWizardPage extends WizardPage {
];
this.host.isValid = true;
}}
?disabled=${type.requiresEnterprise ? !this.enterprise?.hasLicense : false}
?disabled=${type.requiresEnterprise ? this.enterprise?.hasLicense : false}
/>
<label class="pf-c-radio__label" for=${`${type.component}-${type.modelName}`}
>${type.name}</label
@ -114,6 +115,7 @@ export class PropertyMappingWizard extends AKElement {
<ak-property-mapping-wizard-initial
slot="initial"
.mappingTypes=${this.mappingTypes}
.enterprise=${this.enterprise}
>
</ak-property-mapping-wizard-initial>
${this.mappingTypes.map((type) => {

View file

@ -83,8 +83,12 @@ export class RacInterface extends Interface {
// Keep track of current connection attempt
connectionAttempt = 0;
static domSize(): DOMRect {
return document.body.getBoundingClientRect();
static domSize(): { width: number; height: number } {
const size = document.body.getBoundingClientRect();
return {
width: size.width * window.devicePixelRatio,
height: size.height * window.devicePixelRatio,
};
}
constructor() {