mirror of
https://github.com/goharbor/harbor.git
synced 2024-09-07 11:38:07 +02:00
Merge pull request #1390 from wknet123/configuration
Add configuration of UI.
This commit is contained in:
commit
4bc69f294f
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
.switch-pane-admin-options {
|
.switch-pane-admin-options {
|
||||||
display: inline;
|
display: inline;
|
||||||
width: 245px;
|
width: 340px;
|
||||||
float: right;
|
float: right;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
}
|
}
|
||||||
@ -29,3 +29,7 @@
|
|||||||
border-bottom: 2px solid rgb(0, 84, 190);
|
border-bottom: 2px solid rgb(0, 84, 190);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inline-help-config {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
@ -12,65 +12,224 @@
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<form name="form" class="form-horizontal" ng-submit="form.$valid && vm.changeSettings(system)" autocomplete="off">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<ul id="ulTabHeader" class="nav nav-pills nav-stacked col-md-2 col-xs-12">
|
||||||
<h5>System Settings</h5>
|
<li role="presentation"><a href="#auth" aria-controls="auth" role="tab" data-toggle="tab">// 'authentication' | tr //</a></li>
|
||||||
<hr/>
|
<li role="presentation"><a href="#email" aria-controls="email" role="tab" data-toggle="tab">// 'email_settings' | tr //</a></li>
|
||||||
</div>
|
<li role="presentation"><a href="#system" aria-controls="system" role="tab" data-toggle="tab">// 'system_settings' | tr //</a></li>
|
||||||
<div class="col-md-12 col-md-off-set-1 main-content">
|
</ul>
|
||||||
|
<!-- Tab panes -->
|
||||||
|
<div id="tabConfigurations" class="tab-content col-md-10 col-xs-12">
|
||||||
|
<div role="tabpanel" class="tab-pane" id="auth">
|
||||||
|
<form name="authForm" class="form-horizontal" no-validate autocomplete="off">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="hostName" class="col-sm-3 control-label">Host Name:</label>
|
<label for="selAuth" class="col-sm-3 control-label">// 'authentication_mode' | tr //<span ng-if="vm.warning['auth.authMode']">*</span></label>
|
||||||
<div class="col-sm-7">
|
<div class="col-sm-2">
|
||||||
<input type="text" class="form-control" id="hostName" ng-model="system.hostName" ng-model-options="{ updateOn: 'blur' }" ng-value="vm.system.hostName" name="uHostName" required>
|
<select id="selAuth" class="form-control" ng-model="auth.authMode.data" ng-options="r as r.name for r in vm.supportedAuths track by r.value" ng-disabled="!vm.editable['auth.authMode']"></select>
|
||||||
<div ng-messages="form.$dirty && form.uHostName.$error">
|
|
||||||
<span ng-message="required">Host name is required.</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="inline-help-config">
|
||||||
|
<inline-help help-title="// 'authentication_mode' | tr //" content="// 'authentication_mode_desc' | tr //"></inline-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" ng-if="auth.authMode.data.value !== 'ldap_auth'">
|
||||||
|
<label for="selfRegistration" class="col-sm-3 control-label">// 'self_registration' | tr //<span ng-if="vm.warning['auth.selfRegistration']">*</span></label>
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<select class="form-control" ng-model="auth.selfRegistration.data" ng-options="r as r.name for r in vm.toggleBooleans track by r.value" ng-disabled="!vm.editable['auth.selfRegistration']"></select>
|
||||||
|
</div>
|
||||||
|
<div class="inline-help-config">
|
||||||
|
<inline-help help-title="// 'self_registration' | tr //" content="// 'self_registration_desc' | tr //"></inline-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" ng-if="auth.authMode.data.value === 'ldap_auth'">
|
||||||
|
<label for="ldapURL" class="col-sm-3 control-label">// 'ldap_url' | tr //<span ng-if="vm.warning['auth.ldapURL']">*</span></label>
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<input id="ldapURL" type="text" class="form-control" ng-model="auth.ldapURL.data" ng-disabled="!vm.editable['auth.ldapURL']">
|
||||||
|
</div>
|
||||||
|
<div class="inline-help-config">
|
||||||
|
<inline-help help-title="// 'ldap_url' | tr //" content="// 'ldap_url_desc' | tr //"></inline-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" ng-if="auth.authMode.data.value === 'ldap_auth'">
|
||||||
|
<label for="ldapSearchDN" class="col-sm-3 control-label">// 'ldap_search_dn' | tr //<span ng-if="vm.warning['auth.ldapSearchDN']">*</span></label>
|
||||||
|
<div class="col-sm-5 clearfix">
|
||||||
|
<input id="ldapSearchDN" type="text" class="form-control" ng-model="auth.ldapSearchDN.data" ng-disabled="!vm.editable['auth.ldapSearchDN']">
|
||||||
|
</div>
|
||||||
|
<div class="inline-help-config">
|
||||||
|
<inline-help help-title="// 'ldap_search_dn' | tr //" content="// 'ldap_search_dn_desc' | tr //"></inline-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" ng-if="auth.authMode.data.value === 'ldap_auth'">
|
||||||
|
<label for="ldapSearchPassword" class="col-sm-3 control-label">// 'ldap_search_password' | tr //<span ng-if="vm.warning['auth.ldapSearchPassword']">*</span></label>
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<input id="ldapSearchPassword" type="password" class="form-control" ng-model="auth.ldapSearchPassword.data" ng-click="vm.clearUp(auth.ldapSearchPassword)" ng-change="vm.hasChanged(auth.ldapSearchPassword)" ng-blur="vm.setMaskPassword(auth.ldapSearchPassword)">
|
||||||
|
</div>
|
||||||
|
<div class="inline-help-config">
|
||||||
|
<inline-help help-title="// 'ldap_search_password' | tr //" content="// 'ldap_search_password_desc' | tr //"></inline-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" ng-if="auth.authMode.data.value === 'ldap_auth'">
|
||||||
|
<label for="ldapBaseDN" class="col-sm-3 control-label">// 'ldap_base_dn' | tr //<span ng-if="vm.warning['auth.ldapBaseDN']">*</span></label>
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<input id="ldapBaseDN" type="text" class="form-control" ng-model="auth.ldapBaseDN.data" ng-disabled="!vm.editable['auth.ldapBaseDN']">
|
||||||
|
</div>
|
||||||
|
<div class="inline-help-config">
|
||||||
|
<inline-help help-title="// 'ldap_base_dn' | tr //" content="// 'ldap_base_dn_desc' | tr //"></inline-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" ng-if="auth.authMode.data.value === 'ldap_auth'">
|
||||||
|
<label for="ldapUID" class="col-sm-3 control-label">// 'ldap_uid' | tr //<span ng-if="vm.warning['auth.ldapUID']">*</span></label>
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<input id="ldapUID" type="text" class="form-control" ng-model="auth.ldapUID.data" ng-disabled="!vm.editable['auth.ldapUID']">
|
||||||
|
</div>
|
||||||
|
<div class="inline-help-config">
|
||||||
|
<inline-help help-title="// 'ldap_uid' | tr //" content="// 'ldap_uid_desc' | tr //"></inline-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" ng-if="auth.authMode.data.value === 'ldap_auth'">
|
||||||
|
<label for="ldapFilter" class="col-sm-3 control-label">// 'ldap_filter' | tr //<span ng-if="vm.warning['auth.ldapFilter']">*</span></label>
|
||||||
|
<div class="col-sm-5 clearfix">
|
||||||
|
<input id="ldapFilter" type="text" class="form-control" ng-model="auth.ldapFilter.data" ng-disabled="!vm.editable['auth.ldapFilter']">
|
||||||
|
</div>
|
||||||
|
<div class="inline-help-config">
|
||||||
|
<inline-help help-title="// 'ldap_filter' | tr //" content="// 'ldap_filter_desc' | tr //"></inline-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" ng-if="auth.authMode.data.value === 'ldap_auth'">
|
||||||
|
<label for="ldapTimeout" class="col-sm-3 control-label">// 'ldap_connection_timeout' | tr //<span ng-if="vm.warning['auth.ldapConnectionTimeout']">*</span></label>
|
||||||
|
<div class="col-sm-2 clearfix">
|
||||||
|
<input id="ldapConnectionTimeout" type="number" class="form-control" name="ldapConnectionTimeout" ng-model="auth.ldapConnectionTimeout.data" ng-disabled="!vm.editable['auth.ldapConnectionTimeout']" min="1" max="60" required>
|
||||||
|
<div class="error-message" ng-messages="authForm.ldapConnectionTimeout.$error" >
|
||||||
|
<span ng-message="required">// 'timeout_is_required' | tr //</span>
|
||||||
|
<span ng-message="min">// 'invalid_timeout' | tr //</span>
|
||||||
|
<span ng-message="max">// 'invalid_timeout' | tr //</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" ng-if="auth.authMode.data.value === 'ldap_auth'">
|
||||||
|
<label for="selLDAPScope" class="col-sm-3 control-label">// 'ldap_scope' | tr //<span ng-if="vm.warning['auth.ldapScope']">*</span></label>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<select id="selLDAPScope" class="form-control" ng-model="auth.ldapScope.data" ng-options="item for item in [1, 2, 3]" ng-disabled="!vm.editable['auth.ldapScope']"></select>
|
||||||
|
</div>
|
||||||
|
<div class="inline-help-config">
|
||||||
|
<inline-help help-title="// 'ldap_scope' | tr //" content="// 'ldap_scope_desc' | tr //"></inline-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group" ng-if="auth.authMode.data.value === 'ldap_auth'">
|
||||||
|
<div class="col-sm-7 col-sm-offset-3">
|
||||||
|
<span ng-if="vm.isError" class="error-message" >// vm.pingMessage //</span>
|
||||||
|
<span ng-if="!vm.isError">// vm.pingMessage //</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="urlProtocol" class="col-sm-3 control-label">URL Protocol:</label>
|
<div class="col-sm-offset-3 col-sm-5">
|
||||||
<div class="col-sm-7">
|
<div class="pull-right">
|
||||||
<input type="text" class="form-control" id="urlProtocol" ng-model="system.urlProtocol" ng-model-options="{ updateOn: 'blur' }" ng-value="vm.system.urlProtocol" name="uUrlProtocol" required>
|
<button type="submit" class="btn btn-link" ng-if="vm.changed" ng-click="vm.undo()">// 'undo' | tr //</button>
|
||||||
<div ng-messages="form.$dirty && form.uUrlProtocol.$error">
|
<button type="button" class="btn btn-default" ng-if="auth.authMode.data.value === 'ldap_auth'" ng-disabled="authForm.$invalid" ng-click="vm.pingLDAP(auth)" loading-progress hide-target="false" toggle-in-progress="vm.pingTIP">// 'test_connection' | tr //</button>
|
||||||
<span ng-message="required">Url protocol is required.</span>
|
<button type="submit" class="btn btn-success" ng-disabled="authForm.$invalid" ng-click="vm.saveAuthConf(auth)">// 'save' | tr //</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div role="tabpanel" class="tab-pane" id="email">
|
||||||
|
<form name="emailForm" class="form-horizontal" novalidate autocomplete="off">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="emailServer" class="col-sm-3 control-label">// 'email_server' | tr //<span ng-if="vm.warning['email.server']">*</span></label>
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<input id="emailServer" type="text" class="form-control" ng-model="email.server.data" ng-disabled="!vm.editable['email.server']">
|
||||||
|
</div>
|
||||||
|
<div class="inline-help-config">
|
||||||
|
<inline-help help-title="// 'email_server' | tr //" content="// 'email_server_desc' | tr //"></inline-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="emailServer" class="col-sm-3 control-label">Email server:</label>
|
<label for="emailServerPort" class="col-sm-3 control-label">// 'email_server_port' | tr //<span ng-if="vm.warning['email.serverPort']">*</span></label>
|
||||||
<div class="col-sm-7">
|
<div class="col-sm-5">
|
||||||
<input type="text" class="form-control" id="emailServer" ng-model="system.emailServer" ng-model-options="{ updateOn: 'blur' }" ng-value="vm.system.emailServer" name="uEmailServer" required>
|
<input id="emailServerPort" type="number" class="form-control" ng-model="email.serverPort.data" name="emailServerPort" ng-disabled="!vm.editable['email.serverPort']" min="1" max="65535">
|
||||||
<div ng-messages="form.$dirty && form.uEmailServer.$error">
|
<div class="error-message" ng-messages="emailForm.emailServerPort.$error" >
|
||||||
<span ng-message="required">Email server is required.</span>
|
<span ng-message="min">// 'invalid_port_number' | tr //</span>
|
||||||
|
<span ng-message="max">// 'invalid_port_number' | tr //</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="inline-help-config">
|
||||||
<div class="form-group">
|
<inline-help help-title="// 'email_server_port' | tr //" content="// 'email_server_port_desc' | tr //"></inline-help>
|
||||||
<label for="ldapUrl" class="col-sm-3 control-label">LDAP URL:</label>
|
|
||||||
<div class="col-sm-7">
|
|
||||||
<input type="text" class="form-control" id="ldapUrl" ng-model="system.ldapUrl" ng-model-options="{ updateOn: 'blur' }" ng-value="vm.system.ldapUrl" name="uLdapUrl" required>
|
|
||||||
<div ng-messages="form.$dirty && form.uLdapUrl.$error">
|
|
||||||
<span ng-message="required">LDAP URL is required.</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-12">
|
|
||||||
<h5>Registration</h5>
|
|
||||||
<hr/>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-12 col-md-off-set-1 main-content">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="registration" class="col-sm-3 control-label">Registration:</label>
|
|
||||||
<div class="col-sm-7">
|
|
||||||
<select class="form-control" ng-model="vm.currentRegistration" ng-options="r as r.name for r in vm.registrationOptions track by r.value" ng-click="vm.selectRegistration()"></select>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="col-md-offset-7 col-md-10">
|
<label for="emailUsername" class="col-sm-3 control-label">// 'email_username' | tr //<span ng-if="vm.warning['email.username']">*</span></label>
|
||||||
<input type="submit" class="btn btn-primary" ng-disabled="form.$invalid" value="Save">
|
<div class="col-sm-5">
|
||||||
<input type="submit" class="btn btn-default" ng-click="vm.cancel()" value="Cancel">
|
<input id="emailServerPort" type="text" class="form-control" ng-model="email.username.data" ng-disabled="!vm.editable['email.username']">
|
||||||
|
</div>
|
||||||
|
<div class="inline-help-config">
|
||||||
|
<inline-help help-title="// 'email_username' | tr //" content="// 'email_username_desc' | tr //"></inline-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="emailPassword" class="col-sm-3 control-label">// 'email_password' | tr //<span ng-if="vm.warning['email.password']">*</span></label>
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<input id="emailPassword" type="password" class="form-control" ng-model="email.password.data" ng-click="vm.clearUp(email.password)" ng-change="vm.hasChanged(email.password)" ng-blur="vm.setMaskPassword(email.password)">
|
||||||
|
</div>
|
||||||
|
<div class="inline-help-config">
|
||||||
|
<inline-help help-title="// 'email_password' | tr //" content="// 'email_password_desc' | tr //"></inline-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="emailFrom" class="col-sm-3 control-label">// 'email_from' | tr //<span ng-if="vm.warning['email.from']">*</span></label>
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<input id="emailFrom" type="text" class="form-control" ng-model="email.from.data" ng-disabled="!vm.editable['email.from']">
|
||||||
|
</div>
|
||||||
|
<div class="inline-help-config">
|
||||||
|
<inline-help help-title="// 'email_from' | tr //" content="// 'email_from_desc' | tr //"></inline-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="emailSSL" class="col-sm-3 control-label">// 'email_ssl' | tr //<span ng-if="vm.warning['email.SSL']">*</span></label>
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<select class="form-control" ng-model="email.SSL.data" ng-options="r as r.name for r in vm.toggleBooleans track by r.value" ng-disabled="!vm.editable['email.SSL']"></select>
|
||||||
|
</div>
|
||||||
|
<div class="inline-help-config">
|
||||||
|
<inline-help help-title="// 'email_ssl' | tr //" content="// 'email_ssl_desc' | tr //"></inline-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-offset-3 col-sm-5">
|
||||||
|
<div class="pull-right">
|
||||||
|
<button type="submit" class="btn btn-link" ng-if="vm.changed" ng-click="vm.undo()">// 'undo' | tr //</button>
|
||||||
|
<button type="submit" class="btn btn-success" ng-disabled="emailForm.$invalid" ng-click="vm.saveEmailConf(email)">// 'save' | tr //</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
</div>
|
||||||
|
<div role="tabpanel" class="tab-pane" id="system">
|
||||||
|
<form name="systemForm" class="form-horizontal" no-validate autocomplete="off">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="projectCreationRestriction" class="col-sm-3 control-label">// 'project_creation_restriction' | tr //<span ng-if="vm.warning['system.projectCreationRestriction']">*</span></label>
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<select id="projectCreationRestriction" class="form-control" ng-model="system.projectCreationRestriction.data" ng-options="r as r.name for r in vm.toggleCustoms track by r.value" ng-disabled="!vm.editable['system.projectCreationRestriction']"></select>
|
||||||
|
</div>
|
||||||
|
<div class="inline-help-config">
|
||||||
|
<inline-help help-title="// 'project_creation_restriction' | tr //" content="// 'project_creation_restriction_desc' | tr //"></inline-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="verifyRemoteCert" class="col-sm-3 control-label">// 'verify_remote_cert' | tr //<span ng-if="vm.warning['system.verifyRemoteCert']">*</span></label>
|
||||||
|
<div class="col-sm-5">
|
||||||
|
<select id="verifyRemoteCert" class="form-control" ng-model="system.verifyRemoteCert.data" ng-options="r as r.name for r in vm.toggleBooleans track by r.value" ng-disabled="!vm.editable['system.verifyRemoteCert']"></select>
|
||||||
|
</div>
|
||||||
|
<div class="inline-help-config">
|
||||||
|
<inline-help help-title="// 'verify_remote_cert' | tr //" content="// 'verify_remote_cert_desc' | tr //"></inline-help>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-offset-3 col-sm-5">
|
||||||
|
<div class="pull-right">
|
||||||
|
<button type="submit" class="btn btn-link" ng-if="vm.changed" ng-click="vm.undo()">// 'undo' | tr //</button>
|
||||||
|
<button type="submit" class="btn btn-success" ng-disabled="systemForm.$invalid" ng-click="vm.saveSystemConf(system)">// 'save' | tr //</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -18,51 +18,365 @@
|
|||||||
|
|
||||||
angular
|
angular
|
||||||
.module('harbor.system.management')
|
.module('harbor.system.management')
|
||||||
|
.constant('defaultPassword', '12345678')
|
||||||
.directive('configuration', configuration);
|
.directive('configuration', configuration);
|
||||||
|
|
||||||
ConfigurationController.$inject = [];
|
ConfigurationController.$inject = ['$scope', 'ConfigurationService', 'defaultPassword', '$filter', 'trFilter'];
|
||||||
|
|
||||||
function ConfigurationController() {
|
function ConfigurationController($scope, ConfigurationService, defaultPassword, $filter, trFilter) {
|
||||||
var vm = this;
|
var vm = this;
|
||||||
|
|
||||||
vm.registrationOptions = [
|
vm.toggleBooleans = [
|
||||||
{
|
{
|
||||||
'name': 'on',
|
'name': 'True',
|
||||||
'value': true
|
'value': true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'name': 'off',
|
'name': 'False',
|
||||||
'value': false
|
'value': false
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
vm.currentRegistration = {
|
|
||||||
'name': 'on',
|
vm.toggleCustoms = [
|
||||||
'value': true
|
{
|
||||||
|
'name': 'Admin Only',
|
||||||
|
'value': 'adminonly',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'Everyone',
|
||||||
|
'value': 'everyone'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
vm.supportedAuths = [
|
||||||
|
{
|
||||||
|
'name': 'DB auth',
|
||||||
|
'value': 'db_auth'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'name': 'LDAP auth',
|
||||||
|
'value': 'ldap_auth'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
var confKeyDefinitions = {
|
||||||
|
'auth_mode': { type: 'auth', attr: 'authMode' },
|
||||||
|
'self_registration': { type: 'auth', attr: 'selfRegistration' },
|
||||||
|
'ldap_url': { type: 'auth', attr: 'ldapURL' },
|
||||||
|
'ldap_search_dn': { type: 'auth', attr: 'ldapSearchDN' },
|
||||||
|
'ldap_search_password': { type: 'auth', attr: 'ldapSearchPassword' },
|
||||||
|
'ldap_base_dn': { type: 'auth', attr: 'ldapBaseDN' },
|
||||||
|
'ldap_uid': { type: 'auth', attr: 'ldapUID' },
|
||||||
|
'ldap_filter': { type: 'auth', attr: 'ldapFilter' },
|
||||||
|
'ldap_timeout': { type: 'auth', attr: 'ldapConnectionTimeout' },
|
||||||
|
'ldap_scope': { type: 'auth', attr: 'ldapScope' },
|
||||||
|
'email_host': { type: 'email', attr: 'server' },
|
||||||
|
'email_port': { type: 'email', attr: 'serverPort' },
|
||||||
|
'email_username': { type: 'email', attr: 'username' },
|
||||||
|
'email_password': { type: 'email', attr: 'password' },
|
||||||
|
'email_from': { type: 'email', attr: 'from' },
|
||||||
|
'email_ssl': { type: 'email', attr: 'SSL' },
|
||||||
|
'project_creation_restriction': { type: 'system', attr: 'projectCreationRestriction' },
|
||||||
|
'verify_remote_cert': { type: 'system', attr: 'verifyRemoteCert' }
|
||||||
};
|
};
|
||||||
|
|
||||||
vm.changeSettings = changeSettings;
|
$scope.auth = {};
|
||||||
|
$scope.email = {};
|
||||||
|
$scope.system = {};
|
||||||
|
|
||||||
vm.selectRegistration = selectRegistration;
|
vm.retrieve = retrieve;
|
||||||
|
|
||||||
function selectRegistration() {
|
vm.saveAuthConf = saveAuthConf;
|
||||||
|
vm.saveEmailConf = saveEmailConf;
|
||||||
|
vm.saveSystemConf = saveSystemConf;
|
||||||
|
|
||||||
|
vm.gatherUpdateItems = gatherUpdateItems;
|
||||||
|
vm.clearUp = clearUp;
|
||||||
|
vm.hasChanged = hasChanged;
|
||||||
|
vm.setMaskPassword = setMaskPassword;
|
||||||
|
vm.undo = undo;
|
||||||
|
|
||||||
|
vm.pingLDAP = pingLDAP;
|
||||||
|
vm.pingTIP = false;
|
||||||
|
vm.isError = false;
|
||||||
|
vm.pingMessage = '';
|
||||||
|
|
||||||
|
vm.retrieve();
|
||||||
|
|
||||||
|
function retrieve() {
|
||||||
|
|
||||||
|
vm.ldapSearchPasswordChanged = false;
|
||||||
|
vm.emailPasswordChanged = false;
|
||||||
|
vm.changedItems = {};
|
||||||
|
vm.updatedItems = {};
|
||||||
|
vm.warning = {};
|
||||||
|
vm.editable = {};
|
||||||
|
|
||||||
|
ConfigurationService
|
||||||
|
.get()
|
||||||
|
.then(getConfigurationSuccess, getConfigurationFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeSettings(system) {
|
function getConfigurationSuccess(response) {
|
||||||
console.log(system);
|
var data = response.data || [];
|
||||||
|
for(var key in data) {
|
||||||
|
var mappedDef = keyMapping(key);
|
||||||
|
if(mappedDef) {
|
||||||
|
$scope[mappedDef['type']][mappedDef['attr']] = { 'target': mappedDef['type'] + '.' + mappedDef['attr'], 'data': valueMapping(data[key]['value']) };
|
||||||
|
$scope.$watch(mappedDef['type'] + '.' + mappedDef['attr'], onChangedCallback, true);
|
||||||
|
$scope[mappedDef['type']][mappedDef['attr']]['origin'] = { 'target': mappedDef['type'] + '.' + mappedDef['attr'], 'data': valueMapping(data[key]['value']) };
|
||||||
|
vm.editable[mappedDef['type'] + '.' + mappedDef['attr']] = data[key]['editable'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function configuration() {
|
$scope.auth.ldapSearchPassword = { 'target': 'auth.ldapSearchPassword', 'data': defaultPassword};
|
||||||
|
$scope.email.password = { 'target': 'email.password', 'data': defaultPassword};
|
||||||
|
|
||||||
|
$scope.$watch('auth.ldapSearchPassword', onChangedCallback, true);
|
||||||
|
$scope.$watch('email.password', onChangedCallback, true);
|
||||||
|
|
||||||
|
$scope.auth.ldapSearchPassword.actual = { 'target': 'auth.ldapSearchPassword', 'data': ''};
|
||||||
|
$scope.email.password.actual = { 'target': 'email.password', 'data': ''};
|
||||||
|
}
|
||||||
|
|
||||||
|
function keyMapping(confKey) {
|
||||||
|
for (var key in confKeyDefinitions) {
|
||||||
|
if (confKey === key) {
|
||||||
|
return confKeyDefinitions[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function valueMapping(value) {
|
||||||
|
switch(value) {
|
||||||
|
case true:
|
||||||
|
return vm.toggleBooleans[0];
|
||||||
|
case false:
|
||||||
|
return vm.toggleBooleans[1];
|
||||||
|
case 'db_auth':
|
||||||
|
return vm.supportedAuths[0];
|
||||||
|
case 'ldap_auth':
|
||||||
|
return vm.supportedAuths[1];
|
||||||
|
case 'adminonly':
|
||||||
|
return vm.toggleCustoms[0];
|
||||||
|
case 'everyone':
|
||||||
|
return vm.toggleCustoms[1];
|
||||||
|
default:
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChangedCallback(current, previous) {
|
||||||
|
if(!angular.equals(current, previous)) {
|
||||||
|
var compositeKey = current.target.split(".");
|
||||||
|
vm.changed = false;
|
||||||
|
var changedData = {};
|
||||||
|
switch(current.target) {
|
||||||
|
case 'auth.ldapSearchPassword':
|
||||||
|
if(vm.ldapSearchPasswordChanged) {
|
||||||
|
vm.changed = true;
|
||||||
|
changedData = $scope.auth.ldapSearchPassword.actual.data;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'email.password':
|
||||||
|
if(vm.emailPasswordChanged) {
|
||||||
|
vm.changed = true;
|
||||||
|
changedData = $scope.email.password.actual.data;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if(!angular.equals(current.data, $scope[compositeKey[0]][compositeKey[1]]['origin']['data'])) {
|
||||||
|
vm.changed = true;
|
||||||
|
changedData = current.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(vm.changed) {
|
||||||
|
vm.changedItems[current.target] = changedData;
|
||||||
|
vm.warning[current.target] = true;
|
||||||
|
} else {
|
||||||
|
delete vm.changedItems[current.target];
|
||||||
|
vm.warning[current.target] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getConfigurationFailed(response) {
|
||||||
|
console.log('Failed to get configurations.');
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateConfigurationSuccess(response) {
|
||||||
|
$scope.$emit('modalTitle', $filter('tr')('update_configuration_title', []));
|
||||||
|
$scope.$emit('modalMessage', $filter('tr')('successful_update_configuration', []));
|
||||||
|
var emitInfo = {
|
||||||
|
'confirmOnly': true,
|
||||||
|
'contentType': 'text/plain',
|
||||||
|
'action' : function() {
|
||||||
|
vm.retrieve();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$scope.$emit('raiseInfo', emitInfo);
|
||||||
|
console.log('Updated system configuration successfully.');
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateConfigurationFailed() {
|
||||||
|
$scope.$emit('modalTitle', $filter('tr')('update_configuration_title', []));
|
||||||
|
$scope.$emit('modalMessage', $filter('tr')('failed_to_update_configuration', []));
|
||||||
|
$scope.$emit('raiseError', true);
|
||||||
|
console.log('Failed to update system configurations.');
|
||||||
|
}
|
||||||
|
|
||||||
|
function gatherUpdateItems() {
|
||||||
|
vm.updatedItems = {};
|
||||||
|
for(var key in confKeyDefinitions) {
|
||||||
|
var value = confKeyDefinitions[key];
|
||||||
|
var compositeKey = value.type + '.' + value.attr;
|
||||||
|
for(var itemKey in vm.changedItems) {
|
||||||
|
var item = vm.changedItems[itemKey];
|
||||||
|
if (compositeKey === itemKey) {
|
||||||
|
(typeof item === 'object' && item) ? vm.updatedItems[key] = ((typeof item.value === 'boolean') ? Number(item.value) + '' : item.value) : vm.updatedItems[key] = String(item) || '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveAuthConf(auth) {
|
||||||
|
vm.gatherUpdateItems();
|
||||||
|
console.log('auth changed:' + angular.toJson(vm.updatedItems));
|
||||||
|
ConfigurationService
|
||||||
|
.update(vm.updatedItems)
|
||||||
|
.then(updateConfigurationSuccess, updateConfigurationFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveEmailConf(email) {
|
||||||
|
vm.gatherUpdateItems();
|
||||||
|
console.log('email changed:' + angular.toJson(vm.updatedItems));
|
||||||
|
ConfigurationService
|
||||||
|
.update(vm.updatedItems)
|
||||||
|
.then(updateConfigurationSuccess, updateConfigurationFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveSystemConf(system) {
|
||||||
|
vm.gatherUpdateItems();
|
||||||
|
console.log('system changed:' + angular.toJson(vm.updatedItems));
|
||||||
|
ConfigurationService
|
||||||
|
.update(vm.updatedItems)
|
||||||
|
.then(updateConfigurationSuccess, updateConfigurationFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearUp(input) {
|
||||||
|
switch(input.target) {
|
||||||
|
case 'auth.ldapSearchPassword':
|
||||||
|
$scope.auth.ldapSearchPassword.data = '';
|
||||||
|
break;
|
||||||
|
case 'email.password':
|
||||||
|
$scope.email.password.data = '';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasChanged(input) {
|
||||||
|
switch(input.target) {
|
||||||
|
case 'auth.ldapSearchPassword':
|
||||||
|
vm.ldapSearchPasswordChanged = true;
|
||||||
|
$scope.auth.ldapSearchPassword.actual.data = input.data;
|
||||||
|
break;
|
||||||
|
case 'email.password':
|
||||||
|
vm.emailPasswordChanged = true;
|
||||||
|
$scope.email.password.actual.data = input.data;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMaskPassword(input) {
|
||||||
|
input.data = defaultPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
function undo() {
|
||||||
|
vm.retrieve();
|
||||||
|
}
|
||||||
|
|
||||||
|
function pingLDAP(auth) {
|
||||||
|
var keyset = [
|
||||||
|
{'name': 'ldapURL' , 'attr': 'ldap_url'},
|
||||||
|
{'name': 'ldapSearchDN', 'attr': 'ldap_search_dn'},
|
||||||
|
{'name': 'ldapSearchPassword' , 'attr': 'ldap_search_password'},
|
||||||
|
{'name': 'ldapConnectionTimeout', 'attr': 'ldap_connection_timeout'}
|
||||||
|
];
|
||||||
|
var ldapConf = {};
|
||||||
|
|
||||||
|
for(var i = 0; i < keyset.length; i++) {
|
||||||
|
var key = keyset[i];
|
||||||
|
var value;
|
||||||
|
if(key.name === 'ldapSearchPassword') {
|
||||||
|
value = auth[key.name]['actual']['data'];
|
||||||
|
}else {
|
||||||
|
value = auth[key.name]['data'];
|
||||||
|
}
|
||||||
|
ldapConf[key.attr] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
vm.pingMessage = $filter('tr')('pinging_target');
|
||||||
|
vm.pingTIP = true;
|
||||||
|
vm.isError = false;
|
||||||
|
|
||||||
|
ConfigurationService
|
||||||
|
.pingLDAP(ldapConf)
|
||||||
|
.then(pingLDAPSuccess, pingLDAPFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
function pingLDAPSuccess(response) {
|
||||||
|
vm.pingTIP = false;
|
||||||
|
vm.pingMessage = $filter('tr')('successful_ping_target');
|
||||||
|
}
|
||||||
|
|
||||||
|
function pingLDAPFailed(response) {
|
||||||
|
vm.isError = true;
|
||||||
|
vm.pingTIP = false;
|
||||||
|
vm.pingMessage = $filter('tr')('failed_to_ping_target');
|
||||||
|
console.log('Failed to ping LDAP target:' + response.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
configuration.$inject = ['$filter', 'trFilter'];
|
||||||
|
|
||||||
|
function configuration($filter, trFilter) {
|
||||||
var directive = {
|
var directive = {
|
||||||
'restrict': 'E',
|
'restrict': 'E',
|
||||||
'templateUrl': '/static/resources/js/components/system-management/configuration.directive.html',
|
'templateUrl': '/static/resources/js/components/system-management/configuration.directive.html',
|
||||||
'scope': true,
|
'scope': true,
|
||||||
|
'link': link,
|
||||||
'controller': ConfigurationController,
|
'controller': ConfigurationController,
|
||||||
'controllerAs': 'vm',
|
'controllerAs': 'vm',
|
||||||
'bindToController': true
|
'bindToController': true
|
||||||
};
|
};
|
||||||
return directive;
|
return directive;
|
||||||
|
|
||||||
|
function link(scope, element, attrs, ctrl) {
|
||||||
|
element.find('#ulTabHeader a').on('click', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
ctrl.gatherUpdateItems();
|
||||||
|
if(!angular.equals(ctrl.updatedItems, {})) {
|
||||||
|
var emitInfo = {
|
||||||
|
'confirmOnly': true,
|
||||||
|
'contentType': 'text/html',
|
||||||
|
'action' : function() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
scope.$emit('modalTitle', $filter('tr')('caution'));
|
||||||
|
scope.$emit('modalMessage', $filter('tr')('please_save_changes'));
|
||||||
|
scope.$emit('raiseInfo', emitInfo);
|
||||||
|
scope.$apply();
|
||||||
|
e.stopPropagation();
|
||||||
|
}else{
|
||||||
|
$(this).tab('show');
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
element.find('#ulTabHeader a:first').trigger('click');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
})();
|
})();
|
@ -29,6 +29,7 @@
|
|||||||
switch(currentTarget) {
|
switch(currentTarget) {
|
||||||
case 'destinations':
|
case 'destinations':
|
||||||
case 'replication':
|
case 'replication':
|
||||||
|
case 'configuration':
|
||||||
$location.path('/' + currentTarget);
|
$location.path('/' + currentTarget);
|
||||||
vm.target = currentTarget;
|
vm.target = currentTarget;
|
||||||
break;
|
break;
|
||||||
|
@ -12,10 +12,8 @@
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<ul class="switch-pane-admin-options" role="tablist">
|
<ul class="switch-pane-admin-options" role="tablist" ng-style="vm.customPos">
|
||||||
<li><a tag="destinations" href="#/destinations">// 'destination' | tr //</a><span class="gutter">|</span></li>
|
<li><a tag="destinations" href="#/destinations">// 'destination' | tr //</a><span class="gutter">|</span></li>
|
||||||
<li><a tag="replication" href="#/replication">// 'replication' | tr //</a><span class="gutter">
|
<li><a tag="replication" href="#/replication">// 'replication' | tr //</a><span class="gutter">|</span>
|
||||||
<!--
|
<li><a tag="configuration" href="#/configuration">// 'configuration' | tr //</a></li>
|
||||||
<li><a tag="configuration" href="#/configuration">Configuration</a></li>
|
|
||||||
-->
|
|
||||||
</ul>
|
</ul>
|
@ -27,7 +27,9 @@
|
|||||||
vm.path = $location.path();
|
vm.path = $location.path();
|
||||||
}
|
}
|
||||||
|
|
||||||
function navigationAdminOptions() {
|
navigationAdminOptions.$inject = ['I18nService'];
|
||||||
|
|
||||||
|
function navigationAdminOptions(I18nService) {
|
||||||
var directive = {
|
var directive = {
|
||||||
'restrict': 'E',
|
'restrict': 'E',
|
||||||
'templateUrl': '/static/resources/js/layout/navigation/navigation-admin-options.directive.html',
|
'templateUrl': '/static/resources/js/layout/navigation/navigation-admin-options.directive.html',
|
||||||
@ -45,6 +47,13 @@
|
|||||||
var visited = ctrl.path.substring(1);
|
var visited = ctrl.path.substring(1);
|
||||||
console.log('visited:' + visited);
|
console.log('visited:' + visited);
|
||||||
|
|
||||||
|
var lang = I18nService().getCurrentLanguage();
|
||||||
|
ctrl.customPos = {};
|
||||||
|
|
||||||
|
if(lang === 'zh-CN') {
|
||||||
|
ctrl.customPos = {'position': 'relative', 'left': '14%'};
|
||||||
|
}
|
||||||
|
|
||||||
if(visited) {
|
if(visited) {
|
||||||
element.find('a[tag="' + visited + '"]').addClass('active');
|
element.find('a[tag="' + visited + '"]').addClass('active');
|
||||||
}else{
|
}else{
|
||||||
|
@ -35,7 +35,9 @@
|
|||||||
vm.path = $location.path();
|
vm.path = $location.path();
|
||||||
}
|
}
|
||||||
|
|
||||||
function navigationDetails() {
|
navigationDetails.$inject = ['I18nService'];
|
||||||
|
|
||||||
|
function navigationDetails(I18nService) {
|
||||||
var directive = {
|
var directive = {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
templateUrl: '/navigation_detail?timestamp=' + new Date().getTime(),
|
templateUrl: '/navigation_detail?timestamp=' + new Date().getTime(),
|
||||||
@ -53,6 +55,13 @@
|
|||||||
|
|
||||||
function link(scope, element, attrs, ctrl) {
|
function link(scope, element, attrs, ctrl) {
|
||||||
|
|
||||||
|
var lang = I18nService().getCurrentLanguage();
|
||||||
|
ctrl.customPos = {};
|
||||||
|
|
||||||
|
if(lang === 'zh-CN') {
|
||||||
|
ctrl.customPos = {'position': 'relative', 'left': '8%'};
|
||||||
|
}
|
||||||
|
|
||||||
var visited = ctrl.path.substring(1);
|
var visited = ctrl.path.substring(1);
|
||||||
|
|
||||||
if(visited) {
|
if(visited) {
|
||||||
|
@ -287,5 +287,57 @@ var locale_messages = {
|
|||||||
'confirm_to_toggle_enabled_policy': 'After enabling the replication policy, all repositories under the project will be replicated to the destination registry. Please confirm to continue.',
|
'confirm_to_toggle_enabled_policy': 'After enabling the replication policy, all repositories under the project will be replicated to the destination registry. Please confirm to continue.',
|
||||||
'confirm_to_toggle_disabled_policy_title': 'Disable Policy',
|
'confirm_to_toggle_disabled_policy_title': 'Disable Policy',
|
||||||
'confirm_to_toggle_disabled_policy': 'After disabling the policy, all unfinished replication jobs of this policy will be stopped and canceled. Please confirm to continue.',
|
'confirm_to_toggle_disabled_policy': 'After disabling the policy, all unfinished replication jobs of this policy will be stopped and canceled. Please confirm to continue.',
|
||||||
'begin_date_is_later_than_end_date': 'Begin date should not be later than end date.'
|
'begin_date_is_later_than_end_date': 'Begin date should not be later than end date.',
|
||||||
|
'configuration': 'Configuration',
|
||||||
|
'authentication': 'Authentication',
|
||||||
|
'email_settings': 'Email Settings',
|
||||||
|
'system_settings': 'System Settings',
|
||||||
|
'authentication_mode': 'Authentication Mode',
|
||||||
|
'authentication_mode_desc': 'The default authentication mode is db_auth. Set it to ldap_auth when users\' credentials are stored in an LDAP or AD server. Note: this option can only be set once.',
|
||||||
|
'self_registration': 'Self Registration',
|
||||||
|
'self_registration_desc': 'Determine whether the self-registration is allowed or not. Set this to off to disable a user\'s self-registration in Harbor. This flag has no effect when users are stored in LDAP or AD.',
|
||||||
|
'ldap_url': 'LDAP URL',
|
||||||
|
'ldap_url_desc': 'The URL of an LDAP/AD server.',
|
||||||
|
'ldap_search_dn': 'LDAP Search DN',
|
||||||
|
'ldap_search_dn_desc': 'A user\'s DN who has the permission to search the LDAP/AD server. Leave blank if your LDAP/AD server supports anonymous search, otherwise you should configure this DN and LDAP Search Password.',
|
||||||
|
'ldap_search_password': 'LDAP Search Password',
|
||||||
|
'ldap_search_password_desc': 'The password of the user for LDAP search. Leave blank if your LDAP/AD server supports anonymous search.',
|
||||||
|
'ldap_base_dn': 'LDAP Base DN',
|
||||||
|
'ldap_base_dn_desc': 'The base DN of a node from which to look up a user for authentication. The search scope includes subtree of the node.',
|
||||||
|
'ldap_uid': 'LDAP UID',
|
||||||
|
'ldap_uid_desc': '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 server.',
|
||||||
|
'ldap_filter': 'LDAP Filter',
|
||||||
|
'ldap_filter_desc': 'Search filter for LDAP/AD, make sure the syntax of the filter is correct.',
|
||||||
|
'ldap_connection_timeout': 'LDAP Connection Timeout(sec.)',
|
||||||
|
'ldap_scope': 'LDAP Scope',
|
||||||
|
'ldap_scope_desc': 'The scope to search for users.(1-LDAP_SCOPE_BASE, 2-LDAP_SCOPE_ONELEVEL, 3-LDAP_SCOPE_SUBTREE)',
|
||||||
|
'email_server': 'Email Server',
|
||||||
|
'email_server_desc': 'The mail server to send out emails to reset password.',
|
||||||
|
'email_server_port': 'Email Server Port',
|
||||||
|
'email_server_port_desc': 'The port of mail server.',
|
||||||
|
'email_username': 'Email Username',
|
||||||
|
'email_username_desc': 'The user from whom the password reset email is sent. Usually this is a system email address.',
|
||||||
|
'email_password': 'Email Password',
|
||||||
|
'email_password_desc': 'The password of the user from whom the password reset email is sent.',
|
||||||
|
'email_from': 'Email From',
|
||||||
|
'email_from_desc': 'The name of the email sender.',
|
||||||
|
'email_ssl': 'Email SSL',
|
||||||
|
'email_ssl_desc': 'Whether to enable secure mail transmission.',
|
||||||
|
'project_creation_restriction': 'Project Creation Restriction',
|
||||||
|
'project_creation_restriction_desc': 'The flag to control what users have permission to create projects. Be default everyone can create a project, set to "adminonly" such that only admin can create project.',
|
||||||
|
'verify_remote_cert': 'Verify Remote Cert.',
|
||||||
|
'verify_remote_cert_desc': 'Determine whether the image replication should verify the certificate of a remote Harbor registry. Set this flag to off when the remote registry uses a self-signed or untrusted certificate.',
|
||||||
|
'max_job_workers': 'Max Job Workers',
|
||||||
|
'max_job_workers_desc': 'Maximum number of job workers in job service.',
|
||||||
|
'please_save_changes': 'Please save changes before leaving this page.',
|
||||||
|
'undo': 'Undo',
|
||||||
|
'invalid_port_number': 'Invalid port number.',
|
||||||
|
'max_job_workers_is_required': 'Max job workers number is required.',
|
||||||
|
'timeout_is_required': 'Timeout value is required.',
|
||||||
|
'invalid_timeout': 'Invalid timeout value.',
|
||||||
|
'ldap_scope_is_required': 'Scope is required.',
|
||||||
|
'invalid_ldap_scope': 'Invalid Scope value.',
|
||||||
|
'update_configuration_title': 'Update Configuration(s)',
|
||||||
|
'successful_update_configuration': 'Configuration(s) updated successfully.',
|
||||||
|
'failed_to_update_configuration': 'Failed to update configuration.'
|
||||||
};
|
};
|
@ -287,5 +287,57 @@ var locale_messages = {
|
|||||||
'confirm_to_toggle_enabled_policy': '启用策略后,该项目下的所有镜像仓库将复制到目标实例。请确认继续。',
|
'confirm_to_toggle_enabled_policy': '启用策略后,该项目下的所有镜像仓库将复制到目标实例。请确认继续。',
|
||||||
'confirm_to_toggle_disabled_policy_title': '停用策略',
|
'confirm_to_toggle_disabled_policy_title': '停用策略',
|
||||||
'confirm_to_toggle_disabled_policy': '停用策略后,所有未完成的复制任务将被终止和取消。请确认继续。',
|
'confirm_to_toggle_disabled_policy': '停用策略后,所有未完成的复制任务将被终止和取消。请确认继续。',
|
||||||
'begin_date_is_later_than_end_date': '起始日期不能晚于结束日期。'
|
'begin_date_is_later_than_end_date': '起始日期不能晚于结束日期。',
|
||||||
|
'configuration': '设置',
|
||||||
|
'authentication': '认证设置',
|
||||||
|
'email_settings': '邮箱设置',
|
||||||
|
'system_settings': '系统设置',
|
||||||
|
'authentication_mode': '认证模式',
|
||||||
|
'authentication_mode_desc': '默认的认证模式是: 数据库认证。 当用户信息存储在LDAP或AD服务器时,应设置为LDAP认证模式。 注意:该选项只能被设置一次。',
|
||||||
|
'self_registration': '自注册',
|
||||||
|
'self_registration_desc': '确定是否允许或禁止用户自注册。 关闭该项会禁用Harbor用户注册。 当用户数据存储在LDAP或AD时,该选项无效。 ',
|
||||||
|
'ldap_url': 'LDAP URL',
|
||||||
|
'ldap_url_desc': 'LDAP/AD服务URL。',
|
||||||
|
'ldap_search_dn': 'LDAP Search DN',
|
||||||
|
'ldap_search_dn_desc': '提供一个拥有检索LDAP/AD权限的用户DN。 如果LDAP/AD允许匿名访问该项可以置空, 否则需提供用户DN和密码。',
|
||||||
|
'ldap_search_password': 'LDAP Search 密码',
|
||||||
|
'ldap_search_password_desc': '检索LDAP的用户密码。 如果LDAP/AD允许匿名访问该项可以置空。',
|
||||||
|
'ldap_base_dn': 'LDAP Base DN',
|
||||||
|
'ldap_base_dn_desc': '用于查询认证用户的基本DN节点。 检索范围包含子树节点。',
|
||||||
|
'ldap_uid': 'LDAP UID',
|
||||||
|
'ldap_uid_desc': '该属性用于检索匹配用户, 可以是uid, cn, Email, sAMAccountName或是其他属性, 取决于LDAP/AD服务。',
|
||||||
|
'ldap_filter': 'LDAP 过滤器',
|
||||||
|
'ldap_filter_desc': '用于过滤LDAP/AP检索, 请确保正确语法形式。',
|
||||||
|
'ldap_connection_timeout': 'LDAP连接超时(秒)',
|
||||||
|
'ldap_scope': 'LDAP检索范围',
|
||||||
|
'ldap_scope_desc': '指定用户检索范围。(1-LDAP_SCOPE_BASE, 2-LDAP_SCOPE_ONELEVEL, 3-LDAP_SCOPE_SUBTREE)',
|
||||||
|
'email_server': '邮箱服务地址',
|
||||||
|
'email_server_desc': '用以发送重置密码的邮箱服务地址。',
|
||||||
|
'email_server_port': '邮箱服务端口号',
|
||||||
|
'email_server_port_desc': '邮箱服务端口号',
|
||||||
|
'email_username': '邮箱用户名',
|
||||||
|
'email_username_desc': '发送重置密码邮箱的用户。 通常是系统邮箱地址。',
|
||||||
|
'email_password': '邮箱密码',
|
||||||
|
'email_password_desc': '发送重置密码邮箱的密码。',
|
||||||
|
'email_from': '寄信人',
|
||||||
|
'email_from_desc': '邮箱寄信人名。',
|
||||||
|
'email_ssl': '邮箱SSL',
|
||||||
|
'email_ssl_desc': '是否启用安全邮箱传输。',
|
||||||
|
'project_creation_restriction': '项目创建约束',
|
||||||
|
'project_creation_restriction_desc': '此标志用于控制用户是否有权限创建项目。 默认允许任何人创建项目, 当设置为"adminonly"只允许管理员创建项目。',
|
||||||
|
'verify_remote_cert': '验证远程服务证书',
|
||||||
|
'verify_remote_cert_desc': '确定镜像复制是否检查远程Harbor服务证书。 当使用非受信或自签名证书时应该关闭该检查。',
|
||||||
|
'max_job_workers': '最大任务调度数',
|
||||||
|
'max_job_workers_desc': '任务调度服务最大调度数。',
|
||||||
|
'please_save_changes': '请在离开此页之前保存。',
|
||||||
|
'undo': '撤销',
|
||||||
|
'invalid_port_number': '无效的端口号。',
|
||||||
|
'max_job_workers_is_required': '最大任务数为必填项。',
|
||||||
|
'timeout_is_required': '超时时间为必填项。',
|
||||||
|
'invalid_timeout': '无效的超时时间。',
|
||||||
|
'ldap_scope_is_required': '范围值为必填项。',
|
||||||
|
'invalid_ldap_scope': '无效的范围值。',
|
||||||
|
'update_configuration_title': '修改设置',
|
||||||
|
'successful_update_configuration': '修改设置成功。',
|
||||||
|
'failed_to_update_configuration': '修改设置失败。'
|
||||||
};
|
};
|
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
angular.module('harbor.services.system.info')
|
||||||
|
.service('ConfigurationService', ConfigurationService);
|
||||||
|
|
||||||
|
ConfigurationService.$inject = ['$http', '$q', '$timeout'];
|
||||||
|
|
||||||
|
function ConfigurationService($http, $q, $timeout) {
|
||||||
|
this.get = get;
|
||||||
|
this.update = update;
|
||||||
|
this.pingLDAP = pingLDAP;
|
||||||
|
|
||||||
|
function get() {
|
||||||
|
return $http.get('/api/configurations');
|
||||||
|
}
|
||||||
|
|
||||||
|
function update(updates) {
|
||||||
|
return $http.put('/api/configurations', updates);
|
||||||
|
}
|
||||||
|
|
||||||
|
function pingLDAP(ldapConf) {
|
||||||
|
return $http
|
||||||
|
.post('/api/ldap/ping', ldapConf);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
@ -12,7 +12,7 @@
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<ul class="switch-pane-tabs pull-right" {{ if eq .IsAdmin 1 }} style="width: 365px" {{ end }} role="tablist">
|
<ul class="switch-pane-tabs pull-right" {{ if eq .IsAdmin 1 }} style="width: 365px" ng-style="vm.customPos" {{ end }} role="tablist">
|
||||||
<li><a tag="repositories" href="#/repositories?project_id=//vm.projectId//">// 'repositories' | tr //</a><span class="gutter">|</span></li>
|
<li><a tag="repositories" href="#/repositories?project_id=//vm.projectId//">// 'repositories' | tr //</a><span class="gutter">|</span></li>
|
||||||
{{ if eq .IsAdmin 1 }}
|
{{ if eq .IsAdmin 1 }}
|
||||||
<li><a tag="replication" href="#/replication?project_id=//vm.projectId//">// 'replication' | tr //</a><span class="gutter">|</span></li>
|
<li><a tag="replication" href="#/replication?project_id=//vm.projectId//">// 'replication' | tr //</a><span class="gutter">|</span></li>
|
||||||
|
@ -112,6 +112,7 @@
|
|||||||
|
|
||||||
<script src="/static/resources/js/services/system-info/services.system-info.module.js"></script>
|
<script src="/static/resources/js/services/system-info/services.system-info.module.js"></script>
|
||||||
<script src="/static/resources/js/services/system-info/services.volume-info.js"></script>
|
<script src="/static/resources/js/services/system-info/services.volume-info.js"></script>
|
||||||
|
<script src="/static/resources/js/services/system-info/services.system-configuration.js"></script>
|
||||||
|
|
||||||
<script src="/static/resources/js/session/session.module.js"></script>
|
<script src="/static/resources/js/session/session.module.js"></script>
|
||||||
<script src="/static/resources/js/session/session.current-user.js"></script>
|
<script src="/static/resources/js/session/session.current-user.js"></script>
|
||||||
|
Loading…
Reference in New Issue
Block a user