web: start implementing provider list
This commit is contained in:
		
							
								
								
									
										24
									
								
								swagger.yaml
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								swagger.yaml
									
									
									
									
									
								
							| @ -8758,6 +8758,14 @@ definitions: | ||||
|         enum: | ||||
|           - global | ||||
|           - per_provider | ||||
|       assigned_application_slug: | ||||
|         title: Assigned application slug | ||||
|         type: string | ||||
|         readOnly: true | ||||
|       assigned_application_name: | ||||
|         title: Assigned application name | ||||
|         type: string | ||||
|         readOnly: true | ||||
|       verbose_name: | ||||
|         title: Verbose name | ||||
|         type: string | ||||
| @ -8819,6 +8827,14 @@ definitions: | ||||
|         description: User/Group Attribute used for the user part of the HTTP-Basic | ||||
|           Header. If not set, the user's Email address is used. | ||||
|         type: string | ||||
|       assigned_application_slug: | ||||
|         title: Assigned application slug | ||||
|         type: string | ||||
|         readOnly: true | ||||
|       assigned_application_name: | ||||
|         title: Assigned application name | ||||
|         type: string | ||||
|         readOnly: true | ||||
|       verbose_name: | ||||
|         title: Verbose name | ||||
|         type: string | ||||
| @ -8919,6 +8935,14 @@ definitions: | ||||
|         type: string | ||||
|         format: uuid | ||||
|         x-nullable: true | ||||
|       assigned_application_slug: | ||||
|         title: Assigned application slug | ||||
|         type: string | ||||
|         readOnly: true | ||||
|       assigned_application_name: | ||||
|         title: Assigned application name | ||||
|         type: string | ||||
|         readOnly: true | ||||
|       verbose_name: | ||||
|         title: Verbose name | ||||
|         type: string | ||||
|  | ||||
| @ -4,6 +4,10 @@ export class Provider { | ||||
|     pk: number; | ||||
|     name: string; | ||||
|     authorization_flow: string; | ||||
|  | ||||
|     assigned_application_slug?: string; | ||||
|     assigned_application_name?: string; | ||||
|  | ||||
|     verbose_name: string; | ||||
|     verbose_name_plural: string; | ||||
|  | ||||
| @ -11,11 +15,15 @@ export class Provider { | ||||
|         throw Error(); | ||||
|     } | ||||
|  | ||||
|     static get(slug: string): Promise<Provider> { | ||||
|         return DefaultClient.fetch<Provider>(["providers", "all", slug]); | ||||
|     static get(id: number): Promise<Provider> { | ||||
|         return DefaultClient.fetch<Provider>(["providers", "all", id]); | ||||
|     } | ||||
|  | ||||
|     static list(filter?: QueryArguments): Promise<PBResponse<Provider>> { | ||||
|         return DefaultClient.fetch<PBResponse<Provider>>(["providers", "all"], filter); | ||||
|     } | ||||
|  | ||||
|     static adminUrl(rest: string): string { | ||||
|         return `/administration/providers/${rest}`; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| import { html, TemplateResult } from "lit-html"; | ||||
|  | ||||
| export const SLUG_REGEX = "[-a-zA-Z0-9_]+"; | ||||
| export const ID_REGEX = "\d+"; | ||||
|  | ||||
| export class Route { | ||||
|     url: RegExp; | ||||
|  | ||||
| @ -26,7 +26,7 @@ export const SIDEBAR_ITEMS: SidebarItem[] = [ | ||||
|         new SidebarItem("Sources", "/administration/sources/").activeWhen( | ||||
|             `^/sources/(?<slug>${SLUG_REGEX})$`, | ||||
|         ), | ||||
|         new SidebarItem("Providers", "/administration/providers/"), | ||||
|         new SidebarItem("Providers", "/providers"), | ||||
|         new SidebarItem("Outposts", "/administration/outposts/"), | ||||
|         new SidebarItem("Outpost Service Connections", "/administration/outposts/service_connections/"), | ||||
|     ).when((): Promise<boolean> => { | ||||
|  | ||||
							
								
								
									
										128
									
								
								web/src/pages/providers/ProviderListPage.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								web/src/pages/providers/ProviderListPage.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,128 @@ | ||||
| import { gettext } from "django"; | ||||
| import { customElement, html, property, TemplateResult } from "lit-element"; | ||||
| import { Provider } from "../../api/Providers"; | ||||
| import { PBResponse } from "../../api/Client"; | ||||
| import { TablePage } from "../../elements/table/TablePage"; | ||||
|  | ||||
| import "../../elements/buttons/ModalButton"; | ||||
| import "../../elements/buttons/SpinnerButton"; | ||||
| import { TableColumn } from "../../elements/table/Table"; | ||||
|  | ||||
| @customElement("ak-provider-list") | ||||
| export class ProviderListPage extends TablePage<Provider> { | ||||
|     searchEnabled(): boolean { | ||||
|         return true; | ||||
|     } | ||||
|     pageTitle(): string { | ||||
|         return gettext("Provider"); | ||||
|     } | ||||
|     pageDescription(): string { | ||||
|         return gettext("Provide support for protocols like SAML and OAuth to assigned applications."); | ||||
|     } | ||||
|     pageIcon(): string { | ||||
|         return gettext("pf-icon pf-icon-integration"); | ||||
|     } | ||||
|  | ||||
|     @property() | ||||
|     order = "name"; | ||||
|  | ||||
|     apiEndpoint(page: number): Promise<PBResponse<Provider>> { | ||||
|         return Provider.list({ | ||||
|             ordering: this.order, | ||||
|             page: page, | ||||
|             search: this.search || "", | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     columns(): TableColumn[] { | ||||
|         return [ | ||||
|             new TableColumn("Name", "name"), | ||||
|             new TableColumn("Application"), | ||||
|             new TableColumn("Type", "type"), | ||||
|             new TableColumn(""), | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     row(item: Provider): TemplateResult[] { | ||||
|         return [ | ||||
|             html`<a href="#/providers/${item.pk}"> | ||||
|                 ${item.name} | ||||
|             </a>`, | ||||
|             item.assigned_application_name ? | ||||
|                 html`<i class="pf-icon pf-icon-ok"></i> | ||||
|                     ${gettext("Assigned to application ")} | ||||
|                     <a href="#/applications/${item.assigned_application_slug}">${item.assigned_application_name}</a>` : | ||||
|                 html`<i class="pf-icon pf-icon-warning-triangle"></i> | ||||
|                 ${gettext("Warning: Provider not assigned to any application.")}`, | ||||
|             html`${item.verbose_name}`, | ||||
|             html` | ||||
|             <ak-modal-button href="${Provider.adminUrl(`${item.pk}/update/`)}"> | ||||
|                 <ak-spinner-button slot="trigger" class="pf-m-secondary"> | ||||
|                     Edit | ||||
|                 </ak-spinner-button> | ||||
|                 <div slot="modal"></div> | ||||
|             </ak-modal-button>  | ||||
|             <ak-modal-button href="${Provider.adminUrl(`${item.pk}/delete/`)}"> | ||||
|                 <ak-spinner-button slot="trigger" class="pf-m-danger"> | ||||
|                     Delete | ||||
|                 </ak-spinner-button> | ||||
|                 <div slot="modal"></div> | ||||
|             </ak-modal-button> | ||||
|             `, | ||||
|         ]; | ||||
|     } | ||||
|  | ||||
|     renderToolbar(): TemplateResult { | ||||
|         return html` | ||||
|         <ak-dropdown class="pf-c-dropdown"> | ||||
|             <button class="pf-m-primary pf-c-dropdown__toggle" type="button"> | ||||
|                 <span class="pf-c-dropdown__toggle-text">${gettext("Create")}</span> | ||||
|                 <i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i> | ||||
|             </button> | ||||
|             <ul class="pf-c-dropdown__menu" hidden> | ||||
|                 <li> | ||||
|                     <ak-modal-button href="${Provider.adminUrl(`/create/?type=OAuth2Provider`)}"> | ||||
|                         <button slot="trigger" class="pf-c-dropdown__menu-item">${gettext("OAuth2/OpenID Provider")}<br> | ||||
|                             <small> | ||||
|                                 ${gettext("OAuth2 Provider for generic OAuth and OpenID Connect Applications.")} | ||||
|                             </small> | ||||
|                         </button> | ||||
|                         <div slot="modal"></div> | ||||
|                     </ak-modal-button> | ||||
|                 </li> | ||||
|                 <li> | ||||
|                     <ak-modal-button href="${Provider.adminUrl(`/create/?type=ProxyProvider`)}"> | ||||
|                         <button slot="trigger" class="pf-c-dropdown__menu-item">${gettext("Proxy Provider")}<br> | ||||
|                             <small> | ||||
|                                 ${gettext("Protect applications that don't support any of the other Protocols by using a Reverse-Proxy.")} | ||||
|                             </small> | ||||
|                         </button> | ||||
|                         <div slot="modal"></div> | ||||
|                     </ak-modal-button> | ||||
|                 </li> | ||||
|                 <li> | ||||
|                     <ak-modal-button href="${Provider.adminUrl(`/create/?type=SAMLProvider`)}"> | ||||
|                         <button slot="trigger" class="pf-c-dropdown__menu-item">${gettext("SAML Provider")}<br> | ||||
|                             <small> | ||||
|                                 ${gettext("SAML 2.0 Endpoint for applications which support SAML.")} | ||||
|                             </small> | ||||
|                         </button> | ||||
|                         <div slot="modal"></div> | ||||
|                     </ak-modal-button> | ||||
|                 </li> | ||||
|                 <li> | ||||
|                     <ak-modal-button href="${Provider.adminUrl(`/create/saml/from-metadata`)}/"> | ||||
|                         <button slot="trigger" class="pf-c-dropdown__menu-item">${gettext("SAML Provider from Metadata")}<br> | ||||
|                             <small> | ||||
|                                 ${gettext("Create a SAML Provider by importing its Metadata.")} | ||||
|                             </small> | ||||
|                         </button> | ||||
|                         <div slot="modal"></div> | ||||
|                     </ak-modal-button> | ||||
|                 </li> | ||||
|             </ul> | ||||
|         </ak-dropdown> | ||||
|         ${super.renderToolbar()}`; | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										26
									
								
								web/src/pages/providers/ProviderViewPage.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								web/src/pages/providers/ProviderViewPage.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| import { gettext } from "django"; | ||||
| import { customElement, html, LitElement, property, TemplateResult } from "lit-element"; | ||||
| import { Provider } from "../../api/Providers"; | ||||
| import { PBResponse } from "../../api/Client"; | ||||
| import { TablePage } from "../../elements/table/TablePage"; | ||||
|  | ||||
| import "../../elements/buttons/ModalButton"; | ||||
| import "../../elements/buttons/SpinnerButton"; | ||||
| import { TableColumn } from "../../elements/table/Table"; | ||||
|  | ||||
| @customElement("ak-provider-view") | ||||
| export class ProviderViewPage extends LitElement { | ||||
|     @property() | ||||
|     set args(value: { [key: string]: number }) { | ||||
|         this.providerID = value.id; | ||||
|     } | ||||
|  | ||||
|     @property() | ||||
|     set providerID(value: number) { | ||||
|         Provider.get(value).then((app) => (this.provider = app)); | ||||
|     } | ||||
|  | ||||
|     @property({ attribute: false }) | ||||
|     provider?: Provider; | ||||
|  | ||||
| } | ||||
| @ -1,5 +1,5 @@ | ||||
| import { html } from "lit-html"; | ||||
| import { Route, SLUG_REGEX } from "./elements/router/Route"; | ||||
| import { Route, SLUG_REGEX, ID_REGEX } from "./elements/router/Route"; | ||||
|  | ||||
| import "./pages/LibraryPage"; | ||||
| import "./pages/admin-overview/AdminOverviewPage"; | ||||
| @ -10,6 +10,8 @@ import "./pages/flows/FlowViewPage"; | ||||
| import "./pages/events/EventListPage"; | ||||
| import "./pages/events/TransportListPage"; | ||||
| import "./pages/events/RuleListPage"; | ||||
| import "./pages/providers/ProviderListPage"; | ||||
| import "./pages/providers/ProviderViewPage"; | ||||
| import "./pages/property-mappings/PropertyMappingListPage"; | ||||
|  | ||||
| export const ROUTES: Route[] = [ | ||||
| @ -18,6 +20,10 @@ export const ROUTES: Route[] = [ | ||||
|     new Route(new RegExp("^#.*")).redirect("/library"), | ||||
|     new Route(new RegExp("^/library$"), html`<ak-library></ak-library>`), | ||||
|     new Route(new RegExp("^/administration/overview$"), html`<ak-admin-overview></ak-admin-overview>`), | ||||
|     new Route(new RegExp("^/providers$"), html`<ak-provider-list></ak-provider-list>`), | ||||
|     new Route(new RegExp(`^/providers/(?<id>${ID_REGEX})$`)).then((args) => { | ||||
|         return html`<ak-provider-view .args=${args}></ak-provider-view>`; | ||||
|     }), | ||||
|     new Route(new RegExp("^/applications$"), html`<ak-application-list></ak-application-list>`), | ||||
|     new Route(new RegExp(`^/applications/(?<slug>${SLUG_REGEX})$`)).then((args) => { | ||||
|         return html`<ak-application-view .args=${args}></ak-application-view>`; | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer