Implement Robot account expiration

Signed-off-by: FangyuanCheng <fangyuanc@vmware.com>
This commit is contained in:
FangyuanCheng 2019-02-27 11:06:52 +08:00
parent 894f3774b1
commit a2cd2e50fc
10 changed files with 74 additions and 4 deletions

View File

@ -82,6 +82,7 @@ export class Configuration {
email_password?: StringValueItem; email_password?: StringValueItem;
email_insecure: BoolValueItem; email_insecure: BoolValueItem;
verify_remote_cert: BoolValueItem; verify_remote_cert: BoolValueItem;
robot_token_duration: NumberValueItem;
token_expiration: NumberValueItem; token_expiration: NumberValueItem;
cfg_expiration: NumberValueItem; cfg_expiration: NumberValueItem;
scan_all_policy: ComplexValueItem; scan_all_policy: ComplexValueItem;
@ -117,6 +118,7 @@ export class Configuration {
this.email_password = new StringValueItem("", true); this.email_password = new StringValueItem("", true);
this.email_insecure = new BoolValueItem(false, true); this.email_insecure = new BoolValueItem(false, true);
this.token_expiration = new NumberValueItem(30, true); this.token_expiration = new NumberValueItem(30, true);
this.robot_token_duration = new NumberValueItem(30, true);
this.cfg_expiration = new NumberValueItem(30, true); this.cfg_expiration = new NumberValueItem(30, true);
this.verify_remote_cert = new BoolValueItem(false, true); this.verify_remote_cert = new BoolValueItem(false, true);
this.scan_all_policy = new ComplexValueItem({ this.scan_all_policy = new ComplexValueItem({

View File

@ -30,6 +30,21 @@
<span class="tooltip-content">{{'CONFIG.TOOLTIP.TOKEN_EXPIRATION' | translate}}</span> <span class="tooltip-content">{{'CONFIG.TOOLTIP.TOKEN_EXPIRATION' | translate}}</span>
</a> </a>
</div> </div>
<div class="form-group">
<label for="robotTokenExpiration" class="required">{{'ROBOT_ACCOUNT.TOKEN_EXPIRATION' | translate}}</label>
<label for="robotTokenExpiration" aria-haspopup="true" role="tooltip" class="tooltip tooltip-validation tooltip-md tooltip-top-right"
[class.invalid]="robotTokenExpirationInput.invalid && (robotTokenExpirationInput.dirty || robotTokenExpirationInput.touched)">
<input name="robotTokenExpiration" type="text" #robotTokenExpirationInput="ngModel" (ngModelChange)="changeToken($event)" [(ngModel)]="robotTokenExpiration"
required pattern="^[1-9]{1}[0-9]*$" id="robotTokenExpiration" size="20" [disabled]="!robotExpirationEditable">
<span class="tooltip-content">
{{'ROBOT_ACCOUNT.NUMBER_REQUIRED' | translate}}
</span>
</label>
<a href="javascript:void(0)" role="tooltip" aria-haspopup="true" class="tooltip tooltip-top-right">
<clr-icon shape="info-circle" class="info-tips-icon" size="24"></clr-icon>
<span class="tooltip-content">{{'CONFIG.TOOLTIP.ROBOT_TOKEN_EXPIRATION' | translate}}</span>
</a>
</div>
<div class="form-group" *ngIf="canDownloadCert"> <div class="form-group" *ngIf="canDownloadCert">
<label for="certDownloadLink" class="required">{{'CONFIG.ROOT_CERT' | translate}}</label> <label for="certDownloadLink" class="required">{{'CONFIG.ROOT_CERT' | translate}}</label>
<a #certDownloadLink [href]="downloadLink" target="_blank">{{'CONFIG.ROOT_CERT_LINK' | translate}}</a> <a #certDownloadLink [href]="downloadLink" target="_blank">{{'CONFIG.ROOT_CERT_LINK' | translate}}</a>

View File

@ -1,4 +1,4 @@
import { Component, Input, Output, EventEmitter, ViewChild, Inject, OnChanges, SimpleChanges } from '@angular/core'; import { Component, Input, OnInit, Output, EventEmitter, ViewChild, Inject, OnChanges, SimpleChanges } from '@angular/core';
import { NgForm } from '@angular/forms'; import { NgForm } from '@angular/forms';
import { Configuration, StringValueItem } from '../config'; import { Configuration, StringValueItem } from '../config';
import { SERVICE_CONFIG, IServiceConfig } from '../../service.config'; import { SERVICE_CONFIG, IServiceConfig } from '../../service.config';
@ -13,17 +13,19 @@ import {
} from '../../service/index'; } from '../../service/index';
import { from } from 'rxjs'; import { from } from 'rxjs';
const fakePass = 'aWpLOSYkIzJTTU4wMDkx'; const fakePass = 'aWpLOSYkIzJTTU4wMDkx';
const ONE_HOUR_MINUTES: number = 60;
const ONE_DAY_MINUTES: number = 24 * ONE_HOUR_MINUTES;
@Component({ @Component({
selector: 'system-settings', selector: 'system-settings',
templateUrl: './system-settings.component.html', templateUrl: './system-settings.component.html',
styleUrls: ['./system-settings.component.scss', '../registry-config.component.scss'] styleUrls: ['./system-settings.component.scss', '../registry-config.component.scss']
}) })
export class SystemSettingsComponent implements OnChanges { export class SystemSettingsComponent implements OnChanges, OnInit {
config: Configuration = new Configuration(); config: Configuration = new Configuration();
onGoing = false; onGoing = false;
private originalConfig: Configuration; private originalConfig: Configuration;
downloadLink: string; downloadLink: string;
robotTokenExpiration: string;
@Output() configChange: EventEmitter<Configuration> = new EventEmitter<Configuration>(); @Output() configChange: EventEmitter<Configuration> = new EventEmitter<Configuration>();
@Output() readOnlyChange: EventEmitter<boolean> = new EventEmitter<boolean>(); @Output() readOnlyChange: EventEmitter<boolean> = new EventEmitter<boolean>();
@Output() reloadSystemConfig: EventEmitter<any> = new EventEmitter<any>(); @Output() reloadSystemConfig: EventEmitter<any> = new EventEmitter<any>();
@ -51,6 +53,12 @@ export class SystemSettingsComponent implements OnChanges {
this.systemSettings.token_expiration.editable; this.systemSettings.token_expiration.editable;
} }
get robotExpirationEditable(): boolean {
return this.systemSettings &&
this.systemSettings.robot_token_duration &&
this.systemSettings.robot_token_duration.editable;
}
public isValid(): boolean { public isValid(): boolean {
return this.systemSettingsForm && this.systemSettingsForm.valid; return this.systemSettingsForm && this.systemSettingsForm.valid;
} }
@ -76,7 +84,8 @@ export class SystemSettingsComponent implements OnChanges {
public getSystemChanges(allChanges: any) { public getSystemChanges(allChanges: any) {
let changes = {}; let changes = {};
for (let prop in allChanges) { for (let prop in allChanges) {
if (prop === 'token_expiration' || prop === 'read_only' || prop === 'project_creation_restriction') { if (prop === 'token_expiration' || prop === 'read_only' || prop === 'project_creation_restriction'
|| prop === 'robot_token_duration') {
changes[prop] = allChanges[prop]; changes[prop] = allChanges[prop];
} }
} }
@ -165,6 +174,7 @@ export class SystemSettingsComponent implements OnChanges {
ack.state === ConfirmationState.CONFIRMED) { ack.state === ConfirmationState.CONFIRMED) {
let changes = this.getChanges(); let changes = this.getChanges();
this.reset(changes); this.reset(changes);
this.initRobotToken();
} }
} }
@ -203,7 +213,27 @@ export class SystemSettingsComponent implements OnChanges {
this.downloadLink = this.configInfo.systemInfoEndpoint + "/getcert"; this.downloadLink = this.configInfo.systemInfoEndpoint + "/getcert";
} }
} }
ngOnInit() {
this.initRobotToken();
}
private initRobotToken (): void {
if (this.config &&
this.config.robot_token_duration ) {
let robotExpiration = this.config.robot_token_duration.value;
this.robotTokenExpiration = Math.floor(robotExpiration / ONE_DAY_MINUTES) + '';
}
}
changeToken(v: string) {
if (!v || v === "") {
return;
}
if (!(this.config &&
this.config.robot_token_duration)) {
return;
}
this.config.robot_token_duration.value = +v * ONE_DAY_MINUTES;
}
} }

View File

@ -43,6 +43,7 @@
<clr-datagrid [(clrDgSelected)]="selectedRow" [clrDgLoading]="loading"> <clr-datagrid [(clrDgSelected)]="selectedRow" [clrDgLoading]="loading">
<clr-dg-column>{{'ROBOT_ACCOUNT.NAME' | translate}}</clr-dg-column> <clr-dg-column>{{'ROBOT_ACCOUNT.NAME' | translate}}</clr-dg-column>
<clr-dg-column>{{'ROBOT_ACCOUNT.ENABLED_STATE' | translate}}</clr-dg-column> <clr-dg-column>{{'ROBOT_ACCOUNT.ENABLED_STATE' | translate}}</clr-dg-column>
<clr-dg-column>{{'ROBOT_ACCOUNT.EXPIRATION' | translate}}</clr-dg-column>
<clr-dg-column>{{'ROBOT_ACCOUNT.DESCRIPTION' | translate}}</clr-dg-column> <clr-dg-column>{{'ROBOT_ACCOUNT.DESCRIPTION' | translate}}</clr-dg-column>
<clr-dg-row *clrDgItems="let r of robots" [clrDgItem]="r"> <clr-dg-row *clrDgItems="let r of robots" [clrDgItem]="r">
<clr-dg-cell>{{r.name}}</clr-dg-cell> <clr-dg-cell>{{r.name}}</clr-dg-cell>
@ -50,6 +51,7 @@
<clr-icon shape="check-circle" *ngSwitchCase="false" size="20" class="color-green"></clr-icon> <clr-icon shape="check-circle" *ngSwitchCase="false" size="20" class="color-green"></clr-icon>
<clr-icon shape="times-circle" *ngSwitchCase="true" size="16" class="color-red red-position"></clr-icon> <clr-icon shape="times-circle" *ngSwitchCase="true" size="16" class="color-red red-position"></clr-icon>
</clr-dg-cell> </clr-dg-cell>
<clr-dg-cell>{{r.expiresat * 1000 | date: 'short'}}</clr-dg-cell>
<clr-dg-cell>{{r.description}}</clr-dg-cell> <clr-dg-cell>{{r.description}}</clr-dg-cell>
</clr-dg-row> </clr-dg-row>
<clr-dg-footer> <clr-dg-footer>

View File

@ -3,6 +3,7 @@ export class Robot {
id: number; id: number;
name: string; name: string;
description: string; description: string;
expiresat: number;
disabled: boolean; disabled: boolean;
access: { access: {
isPull: boolean; isPull: boolean;

View File

@ -265,7 +265,10 @@
"TOKEN": "Token", "TOKEN": "Token",
"NEW_ROBOT_ACCOUNT": "NEW ROBOT ACCOUNT", "NEW_ROBOT_ACCOUNT": "NEW ROBOT ACCOUNT",
"ENABLED_STATE": "Enabled state", "ENABLED_STATE": "Enabled state",
"NUMBER_REQUIRED":"Field is required and should be an integer other than 0.",
"DESCRIPTION": "Description", "DESCRIPTION": "Description",
"EXPIRATION": "Expiration",
"TOKEN_EXPIRATION":"Robot Token Expiration (Days)",
"ACTION": "Action", "ACTION": "Action",
"EDIT": "Edit", "EDIT": "Edit",
"ITEMS": "items", "ITEMS": "items",
@ -633,6 +636,7 @@
"LDAP_UID": "The attribute used in a search to match a user. It could be uid, cn, email, sAMAccountName or other attributes depending on your LDAP/AD.", "LDAP_UID": "The attribute used in a search to match a user. It could be uid, cn, email, sAMAccountName or other attributes depending on your LDAP/AD.",
"LDAP_SCOPE": "The scope to search for users.", "LDAP_SCOPE": "The scope to search for users.",
"TOKEN_EXPIRATION": "The expiration time (in minutes) of a token created by the token service. Default is 30 minutes.", "TOKEN_EXPIRATION": "The expiration time (in minutes) of a token created by the token service. Default is 30 minutes.",
"ROBOT_TOKEN_EXPIRATION": "The expiration time ( in days) of the token of the robot account, Default is 30 days. Show the number of days converted from minutes and rounds down",
"PRO_CREATION_RESTRICTION": "The flag to define what users have permission to create projects. By default, everyone can create a project. Set to 'Admin Only' so that only an administrator can create a project.", "PRO_CREATION_RESTRICTION": "The flag to define what users have permission to create projects. By default, everyone can create a project. Set to 'Admin Only' so that only an administrator can create a project.",
"ROOT_CERT_DOWNLOAD": "Download the root certificate of registry.", "ROOT_CERT_DOWNLOAD": "Download the root certificate of registry.",
"SCANNING_POLICY": "Set image scanning policy based on different requirements. 'None': No active policy; 'Daily At': Triggering scanning at the specified time everyday.", "SCANNING_POLICY": "Set image scanning policy based on different requirements. 'None': No active policy; 'Daily At': Triggering scanning at the specified time everyday.",

View File

@ -265,6 +265,9 @@
"TOKEN": "Token", "TOKEN": "Token",
"NEW_ROBOT_ACCOUNT": "NEW ROBOT ACCOUNT", "NEW_ROBOT_ACCOUNT": "NEW ROBOT ACCOUNT",
"ENABLED_STATE": "Enabled state", "ENABLED_STATE": "Enabled state",
"EXPIRATION": "Expiration",
"NUMBER_REQUIRED":"Field is required and should be an integer other than 0.",
"TOKEN_EXPIRATION":"Robot Token Expiration (Days)",
"DESCRIPTION": "Description", "DESCRIPTION": "Description",
"ACTION": "Action", "ACTION": "Action",
"EDIT": "Edit", "EDIT": "Edit",
@ -632,6 +635,7 @@
"LDAP_UID": "El atributo usado en una búsqueda para encontrar un usuario. Debe ser el uid, cn, email, sAMAccountName u otro atributo dependiendo del LDAP/AD.", "LDAP_UID": "El atributo usado en una búsqueda para encontrar un usuario. Debe ser el uid, cn, email, sAMAccountName u otro atributo dependiendo del LDAP/AD.",
"LDAP_SCOPE": "El ámbito de búsqueda para usuarios", "LDAP_SCOPE": "El ámbito de búsqueda para usuarios",
"TOKEN_EXPIRATION": "El tiempo de expiración (en minutos) del token creado por el servicio de tokens. Por defecto son 30 minutos.", "TOKEN_EXPIRATION": "El tiempo de expiración (en minutos) del token creado por el servicio de tokens. Por defecto son 30 minutos.",
"ROBOT_TOKEN_EXPIRATION": "El tiempo de caducidad (días) del token de la cuenta del robot, el valor predeterminado es 30 días. Muestra el número de días convertidos de minutos y redondeos.",
"PRO_CREATION_RESTRICTION": "Marca para definir qué usuarios tienen permisos para crear proyectos. Por defecto, todos pueden crear proyectos. Seleccione 'Solo Administradores' para que solamente los administradores puedan crear proyectos.", "PRO_CREATION_RESTRICTION": "Marca para definir qué usuarios tienen permisos para crear proyectos. Por defecto, todos pueden crear proyectos. Seleccione 'Solo Administradores' para que solamente los administradores puedan crear proyectos.",
"ROOT_CERT_DOWNLOAD": "Download the root certificate of registry.", "ROOT_CERT_DOWNLOAD": "Download the root certificate of registry.",
"SCANNING_POLICY": "Set image scanning policy based on different requirements. 'None': No active policy; 'Daily At': Triggering scanning at the specified time everyday.", "SCANNING_POLICY": "Set image scanning policy based on different requirements. 'None': No active policy; 'Daily At': Triggering scanning at the specified time everyday.",

View File

@ -249,6 +249,9 @@
"TOKEN": "gage ", "TOKEN": "gage ",
"NEW_ROBOT_ACCOUNT": "nouveau robot compte ", "NEW_ROBOT_ACCOUNT": "nouveau robot compte ",
"ENABLED_STATE": "état d 'activation", "ENABLED_STATE": "état d 'activation",
"EXPIRATION": "Expiration",
"NUMBER_REQUIRED":"Field is required and should be an integer other than 0.",
"TOKEN_EXPIRATION":"Robot Token Expiration (Days)",
"DESCRIPTION": "Description", "DESCRIPTION": "Description",
"ACTION": "Action", "ACTION": "Action",
"EDIT": "Edit", "EDIT": "Edit",
@ -605,6 +608,7 @@
"LDAP_UID": "Attribut utilisé dans une recherche pour trouver un utilisateur. Cela peut être uid, cn, email, sAMAccountName ou d'autres attributs selon votre LDAP/AD.", "LDAP_UID": "Attribut utilisé dans une recherche pour trouver un utilisateur. Cela peut être uid, cn, email, sAMAccountName ou d'autres attributs selon votre LDAP/AD.",
"LDAP_SCOPE": "Le scope de recherche des utilisateurs.", "LDAP_SCOPE": "Le scope de recherche des utilisateurs.",
"TOKEN_EXPIRATION": "Le temps d'expiration (en minutes) d'un jeton créé par le service de jeton. La valeur par défaut est 30 minutes.", "TOKEN_EXPIRATION": "Le temps d'expiration (en minutes) d'un jeton créé par le service de jeton. La valeur par défaut est 30 minutes.",
"ROBOT_TOKEN_EXPIRATION": "Le délai d'expiration (en jours) du jeton du compte robot est défini par défaut sur 30 jours. Afficher le nombre de jours convertis à partir des minutes et des arrondis",
"PRO_CREATION_RESTRICTION": "L'indicateur pour définir quels utilisateurs ont le droit de créer des projets. Par défaut, tout le monde peut créer un projet. Définissez sur 'Administrateur Seulement' pour que seul un administrateur puisse créer un projet.", "PRO_CREATION_RESTRICTION": "L'indicateur pour définir quels utilisateurs ont le droit de créer des projets. Par défaut, tout le monde peut créer un projet. Définissez sur 'Administrateur Seulement' pour que seul un administrateur puisse créer un projet.",
"ROOT_CERT_DOWNLOAD": "Téléchargez le certificat racine du dépôt.", "ROOT_CERT_DOWNLOAD": "Téléchargez le certificat racine du dépôt.",
"SCANNING_POLICY": "Définissez la politique d'analyse des images en fonction des différentes exigences. 'Aucune' : pas de politique active; 'Tousles jours à' : déclenchement du balayage à l'heure spécifiée tous les jours.", "SCANNING_POLICY": "Définissez la politique d'analyse des images en fonction des différentes exigences. 'Aucune' : pas de politique active; 'Tousles jours à' : déclenchement du balayage à l'heure spécifiée tous les jours.",

View File

@ -263,6 +263,9 @@
"TOKEN": "Token", "TOKEN": "Token",
"NEW_ROBOT_ACCOUNT": "Novo robô conta", "NEW_ROBOT_ACCOUNT": "Novo robô conta",
"ENABLED_STATE": "Enabled state", "ENABLED_STATE": "Enabled state",
"EXPIRATION": "Expiration",
"NUMBER_REQUIRED":"Field is required and should be an integer other than 0.",
"TOKEN_EXPIRATION":"Robot Token Expiration (Days)",
"DESCRIPTION": "Descrição", "DESCRIPTION": "Descrição",
"ACTION": "AÇÃO", "ACTION": "AÇÃO",
"EDIT": "Editar", "EDIT": "Editar",
@ -626,6 +629,7 @@
"LDAP_UID": "O atributo utilizado na busca de um uusário. Pode ser uid, cn, email, sAMAccountName ou outro atributo dependendo LDAP/AD.", "LDAP_UID": "O atributo utilizado na busca de um uusário. Pode ser uid, cn, email, sAMAccountName ou outro atributo dependendo LDAP/AD.",
"LDAP_SCOPE": "O escopo de busca de usuários.", "LDAP_SCOPE": "O escopo de busca de usuários.",
"TOKEN_EXPIRATION": "O tempo de expiração (em minutos) de um token criado pelo serviço de token. O padrão é 30 minutos.", "TOKEN_EXPIRATION": "O tempo de expiração (em minutos) de um token criado pelo serviço de token. O padrão é 30 minutos.",
"ROBOT_TOKEN_EXPIRATION": "O tempo de expiração (dias) do token da conta do robô, o padrão é 30 dias. Mostra o número de dias convertidos de minutos e arredonda para baixo",
"PRO_CREATION_RESTRICTION": "A opção para definir quais usuários possuem permissão de criar projetos. Por padrão, qualquer um pode criar projetos. Configure para 'Apenas Administradores' para que apenas Administradores possam criar projetos.", "PRO_CREATION_RESTRICTION": "A opção para definir quais usuários possuem permissão de criar projetos. Por padrão, qualquer um pode criar projetos. Configure para 'Apenas Administradores' para que apenas Administradores possam criar projetos.",
"ROOT_CERT_DOWNLOAD": "Baixar o certificado raiz do registry.", "ROOT_CERT_DOWNLOAD": "Baixar o certificado raiz do registry.",
"SCANNING_POLICY": "Configura a política de análise das imagens baseado em diferentes requisitos. 'Nenhum': Nenhuma política ativa; 'Diariamente em': Dispara a análise diariamente no horário especificado.", "SCANNING_POLICY": "Configura a política de análise das imagens baseado em diferentes requisitos. 'Nenhum': Nenhuma política ativa; 'Diariamente em': Dispara a análise diariamente no horário especificado.",

View File

@ -264,6 +264,9 @@
"TOKEN": "令牌", "TOKEN": "令牌",
"NEW_ROBOT_ACCOUNT": "添加机器人账户", "NEW_ROBOT_ACCOUNT": "添加机器人账户",
"ENABLED_STATE": "启用状态", "ENABLED_STATE": "启用状态",
"EXPIRATION": "过期时间",
"NUMBER_REQUIRED":"此项为必填项且为不为0的整数.",
"TOKEN_EXPIRATION":"机器人账户令牌过期时间(天)",
"DESCRIPTION": "描述", "DESCRIPTION": "描述",
"ACTION": "操作", "ACTION": "操作",
"EDIT": "编辑", "EDIT": "编辑",
@ -632,6 +635,7 @@
"LDAP_UID": "在搜索中用来匹配用户的属性可以是uid,cn,email,sAMAccountName或者其它LDAP/AD服务器支持的属性。", "LDAP_UID": "在搜索中用来匹配用户的属性可以是uid,cn,email,sAMAccountName或者其它LDAP/AD服务器支持的属性。",
"LDAP_SCOPE": "搜索用户的范围。", "LDAP_SCOPE": "搜索用户的范围。",
"TOKEN_EXPIRATION": "由令牌服务创建的令牌的过期时间分钟默认为30分钟。", "TOKEN_EXPIRATION": "由令牌服务创建的令牌的过期时间分钟默认为30分钟。",
"ROBOT_TOKEN_EXPIRATION": "机器人账户的令牌的过期时间默认为30天,显示的结果为分钟转化的天数并向下取整。",
"PRO_CREATION_RESTRICTION": "用来确定哪些用户有权限创建项目,默认为’所有人‘,设置为’仅管理员‘则只有管理员可以创建项目。", "PRO_CREATION_RESTRICTION": "用来确定哪些用户有权限创建项目,默认为’所有人‘,设置为’仅管理员‘则只有管理员可以创建项目。",
"ROOT_CERT_DOWNLOAD": "下载镜像库根证书.", "ROOT_CERT_DOWNLOAD": "下载镜像库根证书.",
"SCANNING_POLICY": "基于不同需求设置镜像扫描策略。‘无’:不设置任何策略;‘每日定时’:每天在设置的时间定时执行扫描。", "SCANNING_POLICY": "基于不同需求设置镜像扫描策略。‘无’:不设置任何策略;‘每日定时’:每天在设置的时间定时执行扫描。",