web: start implementing provider list
This commit is contained in:
		
							
								
								
									
										24
									
								
								swagger.yaml
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								swagger.yaml
									
									
									
									
									
								
							| @ -8758,6 +8758,14 @@ definitions: | |||||||
|         enum: |         enum: | ||||||
|           - global |           - global | ||||||
|           - per_provider |           - 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: |       verbose_name: | ||||||
|         title: Verbose name |         title: Verbose name | ||||||
|         type: string |         type: string | ||||||
| @ -8819,6 +8827,14 @@ definitions: | |||||||
|         description: User/Group Attribute used for the user part of the HTTP-Basic |         description: User/Group Attribute used for the user part of the HTTP-Basic | ||||||
|           Header. If not set, the user's Email address is used. |           Header. If not set, the user's Email address is used. | ||||||
|         type: string |         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: |       verbose_name: | ||||||
|         title: Verbose name |         title: Verbose name | ||||||
|         type: string |         type: string | ||||||
| @ -8919,6 +8935,14 @@ definitions: | |||||||
|         type: string |         type: string | ||||||
|         format: uuid |         format: uuid | ||||||
|         x-nullable: true |         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: |       verbose_name: | ||||||
|         title: Verbose name |         title: Verbose name | ||||||
|         type: string |         type: string | ||||||
|  | |||||||
| @ -4,6 +4,10 @@ export class Provider { | |||||||
|     pk: number; |     pk: number; | ||||||
|     name: string; |     name: string; | ||||||
|     authorization_flow: string; |     authorization_flow: string; | ||||||
|  |  | ||||||
|  |     assigned_application_slug?: string; | ||||||
|  |     assigned_application_name?: string; | ||||||
|  |  | ||||||
|     verbose_name: string; |     verbose_name: string; | ||||||
|     verbose_name_plural: string; |     verbose_name_plural: string; | ||||||
|  |  | ||||||
| @ -11,11 +15,15 @@ export class Provider { | |||||||
|         throw Error(); |         throw Error(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     static get(slug: string): Promise<Provider> { |     static get(id: number): Promise<Provider> { | ||||||
|         return DefaultClient.fetch<Provider>(["providers", "all", slug]); |         return DefaultClient.fetch<Provider>(["providers", "all", id]); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     static list(filter?: QueryArguments): Promise<PBResponse<Provider>> { |     static list(filter?: QueryArguments): Promise<PBResponse<Provider>> { | ||||||
|         return DefaultClient.fetch<PBResponse<Provider>>(["providers", "all"], filter); |         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"; | import { html, TemplateResult } from "lit-html"; | ||||||
|  |  | ||||||
| export const SLUG_REGEX = "[-a-zA-Z0-9_]+"; | export const SLUG_REGEX = "[-a-zA-Z0-9_]+"; | ||||||
|  | export const ID_REGEX = "\d+"; | ||||||
|  |  | ||||||
| export class Route { | export class Route { | ||||||
|     url: RegExp; |     url: RegExp; | ||||||
|  | |||||||
| @ -26,7 +26,7 @@ export const SIDEBAR_ITEMS: SidebarItem[] = [ | |||||||
|         new SidebarItem("Sources", "/administration/sources/").activeWhen( |         new SidebarItem("Sources", "/administration/sources/").activeWhen( | ||||||
|             `^/sources/(?<slug>${SLUG_REGEX})$`, |             `^/sources/(?<slug>${SLUG_REGEX})$`, | ||||||
|         ), |         ), | ||||||
|         new SidebarItem("Providers", "/administration/providers/"), |         new SidebarItem("Providers", "/providers"), | ||||||
|         new SidebarItem("Outposts", "/administration/outposts/"), |         new SidebarItem("Outposts", "/administration/outposts/"), | ||||||
|         new SidebarItem("Outpost Service Connections", "/administration/outposts/service_connections/"), |         new SidebarItem("Outpost Service Connections", "/administration/outposts/service_connections/"), | ||||||
|     ).when((): Promise<boolean> => { |     ).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 { 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/LibraryPage"; | ||||||
| import "./pages/admin-overview/AdminOverviewPage"; | import "./pages/admin-overview/AdminOverviewPage"; | ||||||
| @ -10,6 +10,8 @@ import "./pages/flows/FlowViewPage"; | |||||||
| import "./pages/events/EventListPage"; | import "./pages/events/EventListPage"; | ||||||
| import "./pages/events/TransportListPage"; | import "./pages/events/TransportListPage"; | ||||||
| import "./pages/events/RuleListPage"; | import "./pages/events/RuleListPage"; | ||||||
|  | import "./pages/providers/ProviderListPage"; | ||||||
|  | import "./pages/providers/ProviderViewPage"; | ||||||
| import "./pages/property-mappings/PropertyMappingListPage"; | import "./pages/property-mappings/PropertyMappingListPage"; | ||||||
|  |  | ||||||
| export const ROUTES: Route[] = [ | export const ROUTES: Route[] = [ | ||||||
| @ -18,6 +20,10 @@ export const ROUTES: Route[] = [ | |||||||
|     new Route(new RegExp("^#.*")).redirect("/library"), |     new Route(new RegExp("^#.*")).redirect("/library"), | ||||||
|     new Route(new RegExp("^/library$"), html`<ak-library></ak-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("^/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$"), html`<ak-application-list></ak-application-list>`), | ||||||
|     new Route(new RegExp(`^/applications/(?<slug>${SLUG_REGEX})$`)).then((args) => { |     new Route(new RegExp(`^/applications/(?<slug>${SLUG_REGEX})$`)).then((args) => { | ||||||
|         return html`<ak-application-view .args=${args}></ak-application-view>`; |         return html`<ak-application-view .args=${args}></ak-application-view>`; | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer