Skip to content

Commit

Permalink
feat(api,ui): allow to disable project creation (#6403)
Browse files Browse the repository at this point in the history
  • Loading branch information
richardlt authored Jan 3, 2023
1 parent 529c54e commit 49f878a
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 152 deletions.
4 changes: 4 additions & 0 deletions engine/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ type Configuration struct {
DisablePurgeDeletion bool `toml:"disablePurgeDeletion" comment:"Allow you to disable the deletion part of the purge. Workflow run will only be marked as delete" json:"disablePurgeDeletion" default:"false"`
TemplateBulkRunnerCount int64 `toml:"templateBulkRunnerCount" comment:"The count of runner that will execute the workflow template bulk operation." json:"templateBulkRunnerCount" default:"10"`
} `toml:"workflow" comment:"######################\n 'Workflow' global configuration \n######################" json:"workflow"`
Project struct {
CreationDisabled bool `toml:"creationDisabled" comment:"Disable project creation for CDS non admin users." json:"creationDisabled" default:"false" commented:"true"`
InfoCreationDisabled string `toml:"infoCreationDisabled" comment:"Optional message to display if project creation is disabled." json:"infoCreationDisabled" default:"" commented:"true"`
} `toml:"project" comment:"######################\n 'Project' global configuration \n######################" json:"project"`
EventBus event.Config `toml:"events" comment:"######################\n Event bus configuration \n######################" json:"events" mapstructure:"events"`
}

Expand Down
4 changes: 3 additions & 1 deletion engine/api/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ func (api *API) configCDNHandler() service.Handler {
func (api *API) configAPIHandler() service.Handler {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
return service.WriteJSON(w, sdk.APIConfig{
DefaultRunRetentionPolicy: api.Config.Workflow.DefaultRetentionPolicy,
DefaultRunRetentionPolicy: api.Config.Workflow.DefaultRetentionPolicy,
ProjectCreationDisabled: api.Config.Project.CreationDisabled,
ProjectInfoCreationDisabled: api.Config.Project.InfoCreationDisabled,
}, http.StatusOK)
}
}
4 changes: 4 additions & 0 deletions engine/api/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,10 @@ func (api *API) postProjectHandler() service.Handler {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
consumer := getUserConsumer(ctx)

if api.Config.Project.CreationDisabled && !isAdmin(ctx) {
return sdk.NewErrorFrom(sdk.ErrForbidden, "project creation is disabled")
}

var p sdk.Project
if err := service.UnmarshalBody(r, &p); err != nil {
return sdk.WrapError(err, "unable to unmarshal body")
Expand Down
4 changes: 3 additions & 1 deletion sdk/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ type ConfigUser struct {
}

type APIConfig struct {
DefaultRunRetentionPolicy string `json:"default_run_retention_policy"`
DefaultRunRetentionPolicy string `json:"default_run_retention_policy"`
ProjectCreationDisabled bool `json:"project_creation_disabled"`
ProjectInfoCreationDisabled string `json:"project_info_creation_disabled,omitempty"`
}

type TCPServer struct {
Expand Down
2 changes: 2 additions & 0 deletions ui/src/app/model/config.service.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
export class APIConfig {
default_run_retention_policy: string;
project_creation_disabled: boolean;
project_info_creation_disabled: string;
}
14 changes: 10 additions & 4 deletions ui/src/app/views/navbar/navbar.component.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
import { Store } from '@ngxs/store';
import { APIConfig } from 'app/model/config.service';
import { Help } from 'app/model/help.model';
import { NavbarProjectData, NavbarRecentData, NavbarSearchItem } from 'app/model/navbar.model';
import { Project } from 'app/model/project.model';
import { AuthSummary } from 'app/model/user.model';
import { NavbarService } from 'app/service/navbar/navbar.service';
import { RouterService } from 'app/service/router/router.service';
import { ProjectStore } from 'app/service/services.module';
import { ConfigService, ProjectStore } from 'app/service/services.module';
import { ThemeStore } from 'app/service/theme/theme.store';
import { WorkflowStore } from 'app/service/workflow/workflow.store';
import { AutoUnsubscribe } from 'app/shared/decorator/autoUnsubscribe';
Expand Down Expand Up @@ -51,9 +52,8 @@ export class NavbarComponent implements OnInit, OnDestroy {
containsResult = false;
projectsSubscription: Subscription;
workflowsSubscription: Subscription;


showNotif = false;
apiConfig: APIConfig;

constructor(
private _navbarService: NavbarService,
Expand All @@ -63,8 +63,14 @@ export class NavbarComponent implements OnInit, OnDestroy {
private _router: Router,
private _theme: ThemeStore,
private _routerService: RouterService,
private _cd: ChangeDetectorRef
private _cd: ChangeDetectorRef,
private _configService: ConfigService
) {
this._configService.getAPIConfig().subscribe(c => {
this.apiConfig = c;
this._cd.markForCheck();
});

this.authSubscription = this._store.select(AuthenticationState.summary).subscribe(s => {
this.currentAuthSummary = s;
this._cd.markForCheck();
Expand Down
80 changes: 50 additions & 30 deletions ui/src/app/views/navbar/navbar.html
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<div id="navbar">
<nz-header [class.not-dark]="!darkActive" class="navbar">
<a href="#" [routerLink]="['/']">
<img src="assets/images/cds.png" class="item" alt="CDS logo"
title="{{'navbar_home' | translate}}" />
<img src="assets/images/cds.png" class="item" alt="CDS logo" title="{{'navbar_home' | translate}}" />
</a>
<ng-container *ngIf="currentAuthSummary">
<a nz-button nzType="link" class="item link" href="#" [routerLink]="['project', 'list', 'all']">
{{ 'navbar_projects' | translate }}
</a>

<button nz-dropdown [nzDropdownMenu]="bookmarks" nz-button nzType="text" [nzClickHide]="true" class="dropdown title">
<button nz-dropdown [nzDropdownMenu]="bookmarks" nz-button nzType="text" [nzClickHide]="true"
class="dropdown title">
Bookmarks <i nz-icon nzType="caret-down" nzTheme="fill"></i>
</button>
<nz-dropdown-menu #bookmarks="nzDropdownMenu">
Expand All @@ -18,7 +18,7 @@
<ng-container *ngSwitchCase="'workflow'">
<li nz-menu-item>
<a class="item" href="#"
[routerLink]="['project', prj.key, 'workflow', prj.workflow_name]">
[routerLink]="['project', prj.key, 'workflow', prj.workflow_name]">
<div class="details">
<div class="title">
{{prj.workflow_name}}
Expand All @@ -33,7 +33,7 @@
<ng-container *ngSwitchCase="'application'">
<li nz-menu-item>
<a class="item" href="#"
[routerLink]="['project', prj.key, 'application', prj.application_name]">
[routerLink]="['project', prj.key, 'application', prj.application_name]">
<div class="details">
<div class="title">
{{prj.application_name}}}
Expand Down Expand Up @@ -68,31 +68,47 @@
</li>
</ul>
</nz-dropdown-menu>
</ng-container>

<ng-container *ngIf="currentAuthSummary">
<ng-container *ngIf="currentAuthSummary.isAdmin() || (apiConfig && !apiConfig.project_creation_disabled)">
<button nz-button nzType="default" [routerLink]="['/project']">
<i nz-icon nzType="plus"></i>
{{ 'navbar_project_create' | translate }}
</button>
</ng-container>
<ng-container
*ngIf="!currentAuthSummary.isAdmin() && apiConfig && apiConfig.project_creation_disabled && apiConfig.project_info_creation_disabled">
<button nz-button nzType="default" [nzTooltipTitle]="createProjectTemplate" nz-tooltip>
<i nz-icon nzType="info-circle" nzTheme="outline"></i>
{{ 'navbar_project_create' | translate }}
</button>
<ng-template #createProjectTemplate>
<markdown [data]="apiConfig.project_info_creation_disabled"></markdown>
</ng-template>
</ng-container>
</ng-container>
<a class="item link" href="#" [routerLink]="['/project']" *ngIf="currentAuthSummary">
{{ 'navbar_project_create' | translate }}
</a>

<div class="right menu details">

<!-- RING -->
<div class="ring" *ngIf="currentAuthSummary">
<nz-tag *ngIf="currentAuthSummary.isMaintainer() && currentAuthSummary.user.ring !== 'ADMIN'"
nzColor="orange">Maintainer</nz-tag>
<nz-tag *ngIf="currentAuthSummary.user.ring === 'ADMIN' && !currentAuthSummary.isAdmin()"
nzColor="orange">
nzColor="#f50">Maintainer</nz-tag>
<nz-tag *ngIf="currentAuthSummary.user.ring === 'ADMIN' && !currentAuthSummary.isAdmin()" nzColor="#f50">
Maintainer
<a class="detail" (click)="mfaLogin()" title="Elevate to admin"><i nz-icon nzType="unlock" nzTheme="fill"></i></a>
<a class="detail" (click)="mfaLogin()" title="Elevate to admin"><i nz-icon nzType="unlock"
nzTheme="fill"></i></a>
</nz-tag>
<nz-tag *ngIf="currentAuthSummary.isAdmin()" nzColor="red">Admin</nz-tag>
<nz-tag *ngIf="currentAuthSummary.isAdmin()" nzColor="#f00">Admin</nz-tag>
</div>

<!-- SEARCH AREA -->
<div class="search" *ngIf="currentAuthSummary">
<nz-input-group [nzSuffix]="suffixIconSearch" nz-popover [nzPopoverContent]="popupSearchTemplate"
nzPopoverPlacement="bottom" nzPopoverTrigger="click">
<input type="text" nz-input placeholder="Search..."
[(ngModel)]="searchValue" (blur)="search()" (click)="search()" (keyup)="search()" />
nzPopoverPlacement="bottom" nzPopoverTrigger="click">
<input type="text" nz-input placeholder="Search..." [(ngModel)]="searchValue" (blur)="search()"
(click)="search()" (keyup)="search()" />
</nz-input-group>
<ng-template #suffixIconSearch>
<i nz-icon nzType="search"></i>
Expand All @@ -114,7 +130,7 @@
</div>
<div nz-col nzSpan="12">
<div nz-tooltip nzTooltipPlacement="left" class="right"
[nzTooltipTitle]="'navbar_search_help_details' | translate">
[nzTooltipTitle]="'navbar_search_help_details' | translate">
<i nz-icon nzType="question-circle" nzTheme="outline"></i>
{{ 'navbar_search_help' | translate }}
</div>
Expand All @@ -133,8 +149,8 @@
<i nz-icon nzType="star" nzTheme="outline" *ngIf="el.favorite"></i>
<div class="content">
<a class="header" (click)="$event.stopPropagation()"
[routerLink]="['/project', el.projectKey]"
title="{{ 'common_project_title' | translate }}{{el.title}}">
[routerLink]="['/project', el.projectKey]"
title="{{ 'common_project_title' | translate }}{{el.title}}">
{{el.title}}
</a>
</div>
Expand All @@ -153,14 +169,13 @@
<i nz-icon nzType="star" nzTheme="outline" *ngIf="el.favorite"></i>
<div class="content">
<a class="header" (click)="$event.stopPropagation()"
[routerLink]="['/project', el.projectKey, 'workflow', el.title]"
title="{{ 'common_workflow_title' | translate }}{{el.title}}">
[routerLink]="['/project', el.projectKey, 'workflow', el.title]"
title="{{ 'common_workflow_title' | translate }}{{el.title}}">
{{el.title}}
</a>
<div class="description">{{'navbar_in_project' | translate}}
<a (click)="$event.stopPropagation()"
[routerLink]="['/project', el.projectKey]"
title="{{ 'common_project_title' | translate }}{{el.title}}">
<a (click)="$event.stopPropagation()" [routerLink]="['/project', el.projectKey]"
title="{{ 'common_project_title' | translate }}{{el.title}}">
{{el.projectKey}}
</a>
</div>
Expand Down Expand Up @@ -211,10 +226,13 @@
<a href="#" [routerLink]="['settings', 'group']">{{ 'navbar_groups' | translate }}</a>
</li>
<li nz-menu-item>
<a href="#" [routerLink]="['settings', 'worker-model']">{{ 'navbar_worker_models' | translate }}</a>
<a href="#" [routerLink]="['settings', 'worker-model']">{{ 'navbar_worker_models' |
translate
}}</a>
</li>
<li nz-menu-item>
<a href="#" [routerLink]="['settings', 'workflow-template']">{{ 'navbar_workflow_templates' |
<a href="#" [routerLink]="['settings', 'workflow-template']">{{ 'navbar_workflow_templates'
|
translate }}</a>
</li>
<li nz-menu-divider></li>
Expand All @@ -224,7 +242,8 @@

<li nz-menu-divider></li>
<li nz-menu-item>
<a href="#" [routerLink]="['settings', 'downloads']">{{ 'navbar_downloads' | translate }}</a>
<a href="#" [routerLink]="['settings', 'downloads']">{{ 'navbar_downloads' | translate
}}</a>
</li>
<li nz-menu-item>
<a href="#" [routerLink]="['docs', '']" target="_blank" rel="noopener noreferrer">{{
Expand Down Expand Up @@ -256,7 +275,8 @@
<nz-dropdown-menu #adminMenu="nzDropdownMenu">
<ul nz-menu>
<li nz-menu-item>
<a href="#" [routerLink]="['admin', 'worker-model-pattern']">Patterns of configuration scripts</a>
<a href="#" [routerLink]="['admin', 'worker-model-pattern']">Patterns of configuration
scripts</a>
</li>
<li nz-menu-item>
<a href="#" [routerLink]="['admin', 'hooks-tasks']">Hooks tasks summary</a>
Expand All @@ -268,4 +288,4 @@
</nz-dropdown-menu>
</ng-container>
</div>
</div>
</nz-header>
Loading

0 comments on commit 49f878a

Please sign in to comment.