core: add flag to globally disable impersonation
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
		| @ -27,6 +27,7 @@ class Capabilities(models.TextChoices): | |||||||
|  |  | ||||||
|     CAN_SAVE_MEDIA = "can_save_media" |     CAN_SAVE_MEDIA = "can_save_media" | ||||||
|     CAN_GEO_IP = "can_geo_ip" |     CAN_GEO_IP = "can_geo_ip" | ||||||
|  |     CAN_IMPERSONATE = "can_impersonate" | ||||||
|  |  | ||||||
|  |  | ||||||
| class ErrorReportingConfigSerializer(PassiveSerializer): | class ErrorReportingConfigSerializer(PassiveSerializer): | ||||||
| @ -63,6 +64,8 @@ class ConfigView(APIView): | |||||||
|             caps.append(Capabilities.CAN_SAVE_MEDIA) |             caps.append(Capabilities.CAN_SAVE_MEDIA) | ||||||
|         if GEOIP_READER.enabled: |         if GEOIP_READER.enabled: | ||||||
|             caps.append(Capabilities.CAN_GEO_IP) |             caps.append(Capabilities.CAN_GEO_IP) | ||||||
|  |         if CONFIG.y_bool("impersonation"): | ||||||
|  |             caps.append(Capabilities.CAN_IMPERSONATE) | ||||||
|         return caps |         return caps | ||||||
|  |  | ||||||
|     @extend_schema(responses={200: ConfigSerializer(many=False)}) |     @extend_schema(responses={200: ConfigSerializer(many=False)}) | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ from django.http import HttpRequest, HttpResponse | |||||||
| from django.shortcuts import get_object_or_404, redirect | from django.shortcuts import get_object_or_404, redirect | ||||||
| from django.views import View | from django.views import View | ||||||
| from structlog.stdlib import get_logger | from structlog.stdlib import get_logger | ||||||
|  | from authentik.lib.config import CONFIG | ||||||
| from authentik.core.middleware import SESSION_IMPERSONATE_ORIGINAL_USER, SESSION_IMPERSONATE_USER | from authentik.core.middleware import SESSION_IMPERSONATE_ORIGINAL_USER, SESSION_IMPERSONATE_USER | ||||||
| from authentik.core.models import User | from authentik.core.models import User | ||||||
| from authentik.events.models import Event, EventAction | from authentik.events.models import Event, EventAction | ||||||
| @ -17,6 +17,9 @@ class ImpersonateInitView(View): | |||||||
|  |  | ||||||
|     def get(self, request: HttpRequest, user_id: int) -> HttpResponse: |     def get(self, request: HttpRequest, user_id: int) -> HttpResponse: | ||||||
|         """Impersonation handler, checks permissions""" |         """Impersonation handler, checks permissions""" | ||||||
|  |         if not CONFIG.y_bool("impersonation"): | ||||||
|  |             LOGGER.debug("User attempted to impersonate", user=request.user) | ||||||
|  |             return HttpResponse("Unauthorized", status=401) | ||||||
|         if not request.user.has_perm("impersonate"): |         if not request.user.has_perm("impersonate"): | ||||||
|             LOGGER.debug("User attempted to impersonate without permissions", user=request.user) |             LOGGER.debug("User attempted to impersonate without permissions", user=request.user) | ||||||
|             return HttpResponse("Unauthorized", status=401) |             return HttpResponse("Unauthorized", status=401) | ||||||
|  | |||||||
| @ -72,3 +72,4 @@ default_user_change_username: true | |||||||
| gdpr_compliance: true | gdpr_compliance: true | ||||||
| cert_discovery_dir: /certs | cert_discovery_dir: /certs | ||||||
| default_token_length: 128 | default_token_length: 128 | ||||||
|  | impersonation: true | ||||||
|  | |||||||
| @ -20087,6 +20087,7 @@ components: | |||||||
|       enum: |       enum: | ||||||
|       - can_save_media |       - can_save_media | ||||||
|       - can_geo_ip |       - can_geo_ip | ||||||
|  |       - can_impersonate | ||||||
|       type: string |       type: string | ||||||
|     CaptchaChallenge: |     CaptchaChallenge: | ||||||
|       type: object |       type: object | ||||||
|  | |||||||
| @ -7,10 +7,10 @@ import { until } from "lit/directives/until.js"; | |||||||
| import PFAlert from "@patternfly/patternfly/components/Alert/alert.css"; | import PFAlert from "@patternfly/patternfly/components/Alert/alert.css"; | ||||||
| import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css"; | import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css"; | ||||||
|  |  | ||||||
| import { CoreApi, User } from "@goauthentik/api"; | import { CapabilitiesEnum, CoreApi, User } from "@goauthentik/api"; | ||||||
|  |  | ||||||
| import { AKResponse } from "../../api/Client"; | import { AKResponse } from "../../api/Client"; | ||||||
| import { DEFAULT_CONFIG, tenant } from "../../api/Config"; | import { DEFAULT_CONFIG, config, tenant } from "../../api/Config"; | ||||||
| import { me } from "../../api/Users"; | import { me } from "../../api/Users"; | ||||||
| import { uiConfig } from "../../common/config"; | import { uiConfig } from "../../common/config"; | ||||||
| import { PFColor } from "../../elements/Label"; | import { PFColor } from "../../elements/Label"; | ||||||
| @ -143,9 +143,19 @@ export class RelatedUserList extends Table<User> { | |||||||
|                         <i class="fas fa-edit"></i> |                         <i class="fas fa-edit"></i> | ||||||
|                     </button> |                     </button> | ||||||
|                 </ak-forms-modal> |                 </ak-forms-modal> | ||||||
|                 <a class="pf-c-button pf-m-tertiary" href="${`/-/impersonation/${item.pk}/`}"> |                 ${until( | ||||||
|                     ${t`Impersonate`} |                     config().then((config) => { | ||||||
|                 </a>`, |                         if (config.capabilities.includes(CapabilitiesEnum.Impersonate)) { | ||||||
|  |                             return html`<a | ||||||
|  |                                 class="pf-c-button pf-m-tertiary" | ||||||
|  |                                 href="${`/-/impersonation/${item.pk}/`}" | ||||||
|  |                             > | ||||||
|  |                                 ${t`Impersonate`} | ||||||
|  |                             </a>`; | ||||||
|  |                         } | ||||||
|  |                         return html``; | ||||||
|  |                     }), | ||||||
|  |                 )}`, | ||||||
|         ]; |         ]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -7,10 +7,10 @@ import { until } from "lit/directives/until.js"; | |||||||
| import PFAlert from "@patternfly/patternfly/components/Alert/alert.css"; | import PFAlert from "@patternfly/patternfly/components/Alert/alert.css"; | ||||||
| import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css"; | import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css"; | ||||||
|  |  | ||||||
| import { CoreApi, User } from "@goauthentik/api"; | import { CapabilitiesEnum, CoreApi, User } from "@goauthentik/api"; | ||||||
|  |  | ||||||
| import { AKResponse } from "../../api/Client"; | import { AKResponse } from "../../api/Client"; | ||||||
| import { DEFAULT_CONFIG, tenant } from "../../api/Config"; | import { DEFAULT_CONFIG, config, tenant } from "../../api/Config"; | ||||||
| import { me } from "../../api/Users"; | import { me } from "../../api/Users"; | ||||||
| import { uiConfig } from "../../common/config"; | import { uiConfig } from "../../common/config"; | ||||||
| import { PFColor } from "../../elements/Label"; | import { PFColor } from "../../elements/Label"; | ||||||
| @ -149,9 +149,19 @@ export class UserListPage extends TablePage<User> { | |||||||
|                         <i class="fas fa-edit"></i> |                         <i class="fas fa-edit"></i> | ||||||
|                     </button> |                     </button> | ||||||
|                 </ak-forms-modal> |                 </ak-forms-modal> | ||||||
|                 <a class="pf-c-button pf-m-tertiary" href="${`/-/impersonation/${item.pk}/`}"> |                 ${until( | ||||||
|                     ${t`Impersonate`} |                     config().then((config) => { | ||||||
|                 </a>`, |                         if (config.capabilities.includes(CapabilitiesEnum.Impersonate)) { | ||||||
|  |                             return html`<a | ||||||
|  |                                 class="pf-c-button pf-m-tertiary" | ||||||
|  |                                 href="${`/-/impersonation/${item.pk}/`}" | ||||||
|  |                             > | ||||||
|  |                                 ${t`Impersonate`} | ||||||
|  |                             </a>`; | ||||||
|  |                         } | ||||||
|  |                         return html``; | ||||||
|  |                     }), | ||||||
|  |                 )}`, | ||||||
|         ]; |         ]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -2,6 +2,7 @@ import { t } from "@lingui/macro"; | |||||||
|  |  | ||||||
| import { CSSResult, LitElement, TemplateResult, html } from "lit"; | import { CSSResult, LitElement, TemplateResult, html } from "lit"; | ||||||
| import { customElement, property } from "lit/decorators.js"; | import { customElement, property } from "lit/decorators.js"; | ||||||
|  | import { until } from "lit/directives/until.js"; | ||||||
|  |  | ||||||
| import AKGlobal from "../../authentik.css"; | import AKGlobal from "../../authentik.css"; | ||||||
| import PFButton from "@patternfly/patternfly/components/Button/button.css"; | import PFButton from "@patternfly/patternfly/components/Button/button.css"; | ||||||
| @ -15,9 +16,9 @@ import PFDisplay from "@patternfly/patternfly/utilities/Display/display.css"; | |||||||
| import PFFlex from "@patternfly/patternfly/utilities/Flex/flex.css"; | import PFFlex from "@patternfly/patternfly/utilities/Flex/flex.css"; | ||||||
| import PFSizing from "@patternfly/patternfly/utilities/Sizing/sizing.css"; | import PFSizing from "@patternfly/patternfly/utilities/Sizing/sizing.css"; | ||||||
|  |  | ||||||
| import { CoreApi, User } from "@goauthentik/api"; | import { CapabilitiesEnum, CoreApi, User } from "@goauthentik/api"; | ||||||
|  |  | ||||||
| import { DEFAULT_CONFIG } from "../../api/Config"; | import { DEFAULT_CONFIG, config } from "../../api/Config"; | ||||||
| import { EVENT_REFRESH } from "../../constants"; | import { EVENT_REFRESH } from "../../constants"; | ||||||
| import "../../elements/CodeMirror"; | import "../../elements/CodeMirror"; | ||||||
| import { PFColor } from "../../elements/Label"; | import { PFColor } from "../../elements/Label"; | ||||||
| @ -239,14 +240,22 @@ export class UserViewPage extends LitElement { | |||||||
|                                 ${t`Reset Password`} |                                 ${t`Reset Password`} | ||||||
|                             </ak-action-button> |                             </ak-action-button> | ||||||
|                         </div> |                         </div> | ||||||
|                         <div class="pf-c-card__footer"> |  | ||||||
|                             <a |                         ${until( | ||||||
|                                 class="pf-c-button pf-m-tertiary" |                             config().then((config) => { | ||||||
|                                 href="${`/-/impersonation/${this.user.pk}/`}" |                                 if (config.capabilities.includes(CapabilitiesEnum.Impersonate)) { | ||||||
|                             > |                                     return html` <div class="pf-c-card__footer"> | ||||||
|                                 ${t`Impersonate`} |                                         <a | ||||||
|                             </a> |                                             class="pf-c-button pf-m-tertiary" | ||||||
|                         </div> |                                             href="${`/-/impersonation/${this.user?.pk}/`}" | ||||||
|  |                                         > | ||||||
|  |                                             ${t`Impersonate`} | ||||||
|  |                                         </a> | ||||||
|  |                                     </div>`; | ||||||
|  |                                 } | ||||||
|  |                                 return html``; | ||||||
|  |                             }), | ||||||
|  |                         )} | ||||||
|                     </div> |                     </div> | ||||||
|                     <div |                     <div | ||||||
|                         class="pf-c-card pf-l-grid__item pf-m-12-col pf-m-9-col-on-xl pf-m-9-col-on-2xl" |                         class="pf-c-card pf-l-grid__item pf-m-12-col pf-m-9-col-on-xl pf-m-9-col-on-2xl" | ||||||
|  | |||||||
| @ -188,6 +188,14 @@ Requires authentik 2022.4.1 | |||||||
|  |  | ||||||
| Configure the length of generated tokens. Defaults to 128. | Configure the length of generated tokens. Defaults to 128. | ||||||
|  |  | ||||||
|  | ### AUTHENTIK_IMPERSONATION | ||||||
|  |  | ||||||
|  | :::info | ||||||
|  | Requires authentik 2022.4.2 | ||||||
|  | ::: | ||||||
|  |  | ||||||
|  | Globally enable/disable impersonation. Defaults to `true`. | ||||||
|  |  | ||||||
| ### AUTHENTIK_FOOTER_LINKS | ### AUTHENTIK_FOOTER_LINKS | ||||||
|  |  | ||||||
| :::info | :::info | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer