367 lines
20 KiB
HTML
367 lines
20 KiB
HTML
<!-- Modal external ldap -->
|
|
<div class="modal fade" id="externalLdapModal" tabindex="-1" role="dialog">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h4 class="modal-title">{{ 'users.externalLdapDialog.title' | tr }}</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<p class="has-error text-center" ng-show="externalLdap.error.generic">{{ externalLdap.error.generic }}</p>
|
|
|
|
<div class="form-group">
|
|
<label class="control-label" for="ldapProvider">{{ 'users.externalLdap.provider' | tr }} <sup><a ng-href="https://docs.cloudron.io/user-management/#external-directory" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup></label>
|
|
<select class="form-control" id="ldapProvider" ng-model="externalLdap.provider" ng-options="a.value as a.name for a in ldapProvider"></select>
|
|
</div>
|
|
|
|
<div uib-collapse="externalLdap.provider === 'noop'">
|
|
<form name="externalLdapConfigForm" role="form" novalidate ng-submit="externalLdap.submit()" autocomplete="off">
|
|
<fieldset>
|
|
<div class="form-group" ng-class="{ 'has-error': externalLdap.error.url }">
|
|
<label class="control-label" for="inputExternalLdapConfigUrl">{{ 'users.externalLdap.server' | tr }}</label>
|
|
<input type="text" class="form-control" ng-model="externalLdap.url" id="inputExternalLdapConfigUrl" name="url" ng-disabled="externalLdap.busy" placeholder="ldaps://example.com:636" required>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" ng-model="externalLdap.acceptSelfSignedCerts"> {{ 'users.externalLdap.acceptSelfSignedCert' | tr }}
|
|
</label>
|
|
</div>
|
|
<p class="has-error" ng-show="externalLdap.error.acceptSelfSignedCerts">{{ 'users.externalLdap.errorSelfSignedCert' | tr }}</p>
|
|
</div>
|
|
|
|
<div class="form-group" ng-class="{ 'has-error': externalLdap.error.baseDn }" ng-show="externalLdap.provider !== 'cloudron'">
|
|
<label class="control-label" for="inputExternalLdapConfigBaseDn">{{ 'users.externalLdap.baseDn' | tr }}</label>
|
|
<input type="text" class="form-control" ng-model="externalLdap.baseDn" id="inputExternalLdapConfigBaseDn" name="baseDn" ng-disabled="externalLdap.busy" placeholder="ou=users,dc=example,dc=com" ng-required="externalLdap.provider !== 'cloudron'">
|
|
</div>
|
|
|
|
<div class="form-group" ng-class="{ 'has-error': externalLdap.error.filter }" ng-show="externalLdap.provider !== 'cloudron'">
|
|
<label class="control-label" for="inputExternalLdapConfigFilter">{{ 'users.externalLdap.filter' | tr }}</label>
|
|
<input type="text" class="form-control" ng-model="externalLdap.filter" id="inputExternalLdapConfigFilter" name="filter" ng-disabled="externalLdap.busy" placeholder="(objectClass=inetOrgPerson)" ng-required="externalLdap.provider !== 'cloudron'">
|
|
</div>
|
|
|
|
<div class="form-group" ng-class="{ 'has-error': externalLdap.error.usernameField }" ng-show="externalLdap.provider !== 'cloudron'">
|
|
<label class="control-label" for="inputExternalLdapConfigUsernameField">{{ 'users.externalLdap.usernameField' | tr }}</label>
|
|
<input type="text" class="form-control" ng-model="externalLdap.usernameField" id="inputExternalLdapConfigUsernameField" name="usernameField" ng-disabled="externalLdap.busy" placeholder="uid or sAMAcountName">
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" ng-model="externalLdap.syncGroups"> {{ 'users.externalLdap.syncGroups' | tr }}</sup>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group" ng-class="{ 'has-error': externalLdap.error.groupBaseDn }" ng-show="externalLdap.syncGroups && externalLdap.provider !== 'cloudron'">
|
|
<label class="control-label" for="inputExternalLdapConfigGroupBaseDn">{{ 'users.externalLdap.groupBaseDn' | tr }}</label>
|
|
<input type="text" class="form-control" ng-model="externalLdap.groupBaseDn" id="inputExternalLdapConfigGroupBaseDn" name="groupBaseDn" ng-disabled="externalLdap.busy" placeholder="ou=groups,dc=example,dc=com" ng-required="externalLdap.syncGroups && externalLdap.provider !== 'cloudron'">
|
|
</div>
|
|
|
|
<div class="form-group" ng-class="{ 'has-error': externalLdap.error.groupFilter }" ng-show="externalLdap.syncGroups && externalLdap.provider !== 'cloudron'">
|
|
<label class="control-label" for="inputExternalLdapConfigGroupFilter">{{ 'users.externalLdap.groupFilter' | tr }}</label>
|
|
<input type="text" class="form-control" ng-model="externalLdap.groupFilter" id="inputExternalLdapConfigGroupFilter" name="groupFilter" ng-disabled="externalLdap.busy" placeholder="(objectClass=groupOfNames)" ng-required="externalLdap.syncGroups && externalLdap.provider !== 'cloudron'">
|
|
</div>
|
|
|
|
<div class="form-group" ng-class="{ 'has-error': externalLdap.error.groupnameField }" ng-show="externalLdap.syncGroups && externalLdap.provider !== 'cloudron'">
|
|
<label class="control-label" for="inputExternalLdapConfigGroupnameField">{{ 'users.externalLdap.groupnameField' | tr }}</label>
|
|
<input type="text" class="form-control" ng-model="externalLdap.groupnameField" id="inputExternalLdapConfigGroupnameField" name="groupnameField" ng-disabled="externalLdap.busy" placeholder="cn" ng-required="externalLdap.syncGroups && externalLdap.provider !== 'cloudron'">
|
|
</div>
|
|
|
|
<div class="form-group" ng-class="{ 'has-error': externalLdap.error.credentials }" ng-show="externalLdap.provider !== 'cloudron'">
|
|
<label class="control-label" for="inputExternalLdapConfigBindDn">{{ 'users.externalLdap.bindUsername' | tr }}</label>
|
|
<input type="text" class="form-control" ng-model="externalLdap.bindDn" id="inputExternalLdapConfigBindDn" name="bindDn" ng-disabled="externalLdap.busy" placeholder="uid=admin,ou=Users,dc=example,dc=com">
|
|
</div>
|
|
|
|
<div class="form-group" ng-class="{ 'has-error': externalLdap.error.credentials }">
|
|
<label class="control-label" for="inputExternalLdapConfigBindPassword">{{ 'users.externalLdap.bindPassword' | tr }}</label>
|
|
<input type="password" class="form-control" ng-model="externalLdap.bindPassword" id="inputExternalLdapConfigBindPassword" name="bindPassword" ng-disabled="externalLdap.busy" placeholder="" password-reveal>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" ng-model="externalLdap.autoCreate"> {{ 'users.externalLdap.autocreateUsersOnLogin' | tr }}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<input class="ng-hide" type="submit" ng-disabled="externalLdapConfigForm.$invalid"/>
|
|
</fieldset>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-default" data-dismiss="modal">{{ 'main.dialog.cancel' | tr }}</button>
|
|
<button type="button" class="btn btn-primary" ng-click="externalLdap.submit()" ng-disabled="externalLdapConfigForm.$invalid || externalLdap.busy"><i class="fa fa-circle-notch fa-spin" ng-show="externalLdap.busy"></i> {{ 'main.dialog.save' | tr }}</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="content content-large">
|
|
|
|
<div class="text-left">
|
|
<h1>
|
|
{{ 'users.settings.title' | tr }}
|
|
</h1>
|
|
</div>
|
|
|
|
<div class="card card-large" ng-show="user.isAtLeastAdmin">
|
|
<form name="profileConfigForm" role="form" novalidate ng-submit="profileConfig.submit()" autocomplete="off">
|
|
<fieldset ng-disabled="profileConfig.busy">
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" ng-model="profileConfig.editableUserProfiles"> {{ 'users.settings.allowProfileEditCheckbox' | tr }} <sup><a ng-href="https://docs.cloudron.io/user-management/#lock-profile" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup>
|
|
</label>
|
|
</div>
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" ng-model="profileConfig.mandatory2FA"> {{ 'users.settings.require2FACheckbox' | tr }}
|
|
</label>
|
|
</div>
|
|
</fieldset>
|
|
</form>
|
|
|
|
<br/>
|
|
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<span class="has-error" ng-show="profileConfig.errorMessage">{{ profileConfig.errorMessage }}</span>
|
|
|
|
<button class="btn btn-outline btn-primary pull-right" ng-click="profileConfig.submit()" ng-disabled="!profileConfigForm.$dirty || profileConfig.busy">
|
|
<i class="fa fa-circle-notch fa-spin" ng-show="profileConfig.busy"></i> {{ 'users.settings.saveAction' | tr }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="text-left section-header" ng-show="user.isAtLeastAdmin">
|
|
<h3>{{ 'users.externalLdap.title' | tr }}</h3>
|
|
</div>
|
|
|
|
<div class="card card-large" ng-show="user.isAtLeastAdmin">
|
|
<div class="row">
|
|
<div class="col-md-12">{{ 'users.externalLdap.description' | tr }}</div>
|
|
</div>
|
|
|
|
<br/>
|
|
|
|
<div class="row" ng-hide="config.features.externalLdap">
|
|
<div class="col-md-12">
|
|
{{ 'users.externalLdap.subscriptionRequired' | tr }} <a href="" class="pull-right" ng-click="openSubscriptionSetup()">{{ 'users.externalLdap.subscriptionRequiredAction' | tr }}</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div ng-show="config.features.externalLdap">
|
|
|
|
<div class="row" ng-show="externalLdap.currentConfig.provider === 'noop'">
|
|
<div class="col-xs-12">
|
|
<span class="text-muted">{{ 'users.externalLdap.noopInfo' | tr }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row" ng-show="externalLdap.currentConfig.provider !== 'noop'">
|
|
<div class="col-xs-6">
|
|
<span class="text-muted">{{ 'users.externalLdap.provider' | tr }}</span>
|
|
</div>
|
|
<div class="col-xs-6 text-right">
|
|
<span>{{ externalLdap.currentConfig.provider }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row" ng-show="externalLdap.currentConfig.provider !== 'noop'">
|
|
<div class="col-xs-6">
|
|
<span class="text-muted">{{ 'users.externalLdap.server' | tr }}</span>
|
|
</div>
|
|
<div class="col-xs-6 text-right">
|
|
<span>{{ externalLdap.currentConfig.url }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row" ng-show="externalLdap.currentConfig.provider !== 'noop'">
|
|
<div class="col-xs-6">
|
|
<span class="text-muted">{{ 'users.externalLdap.acceptSelfSignedCert' | tr }}</span>
|
|
</div>
|
|
<div class="col-xs-6 text-right">
|
|
<span>{{ externalLdap.currentConfig.acceptSelfSignedCerts ? 'Yes' : 'No' }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row" ng-show="externalLdap.currentConfig.provider !== 'noop' && externalLdap.currentConfig.provider !== 'cloudron'">
|
|
<div class="col-xs-6">
|
|
<span class="text-muted">{{ 'users.externalLdap.baseDn' | tr }}</span>
|
|
</div>
|
|
<div class="col-xs-6 text-right">
|
|
<span>{{ externalLdap.currentConfig.baseDn }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row" ng-show="externalLdap.currentConfig.provider !== 'noop' && externalLdap.currentConfig.provider !== 'cloudron'">
|
|
<div class="col-xs-6">
|
|
<span class="text-muted">{{ 'users.externalLdap.filter' | tr }}</span>
|
|
</div>
|
|
<div class="col-xs-6 text-right">
|
|
<span>{{ externalLdap.currentConfig.filter }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row" ng-show="externalLdap.currentConfig.provider !== 'noop' && externalLdap.currentConfig.provider !== 'cloudron'">
|
|
<div class="col-xs-6">
|
|
<span class="text-muted">{{ 'users.externalLdap.usernameField' | tr }}</span>
|
|
</div>
|
|
<div class="col-xs-6 text-right">
|
|
<span>{{ externalLdap.currentConfig.usernameField || 'uid' }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row" ng-show="externalLdap.currentConfig.provider !== 'noop'">
|
|
<div class="col-xs-6">
|
|
<span class="text-muted">{{ 'users.externalLdap.syncGroups' | tr }}</span>
|
|
</div>
|
|
<div class="col-xs-6 text-right">
|
|
<span>{{ externalLdap.currentConfig.syncGroups ? 'Yes' : 'No' }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row" ng-show="externalLdap.currentConfig.provider !== 'noop' && externalLdap.currentConfig.provider !== 'cloudron' && externalLdap.currentConfig.syncGroups">
|
|
<div class="col-xs-6">
|
|
<span class="text-muted">{{ 'users.externalLdap.groupBaseDn' | tr }}</span>
|
|
</div>
|
|
<div class="col-xs-6 text-right">
|
|
<span>{{ externalLdap.currentConfig.groupBaseDn }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row" ng-show="externalLdap.currentConfig.provider !== 'noop' && externalLdap.currentConfig.provider !== 'cloudron' && externalLdap.currentConfig.syncGroups">
|
|
<div class="col-xs-6">
|
|
<span class="text-muted">{{ 'users.externalLdap.groupFilter' | tr }}</span>
|
|
</div>
|
|
<div class="col-xs-6 text-right">
|
|
<span>{{ externalLdap.currentConfig.groupFilter }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row" ng-show="externalLdap.currentConfig.provider !== 'noop' && externalLdap.currentConfig.provider !== 'cloudron' && externalLdap.currentConfig.syncGroups">
|
|
<div class="col-xs-6">
|
|
<span class="text-muted">{{ 'users.externalLdap.groupnameField' | tr }}</span>
|
|
</div>
|
|
<div class="col-xs-6 text-right">
|
|
<span>{{ externalLdap.currentConfig.groupnameField }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row" ng-show="externalLdap.currentConfig.provider !== 'noop' && externalLdap.currentConfig.provider !== 'cloudron'">
|
|
<div class="col-xs-6">
|
|
<span class="text-muted">{{ 'users.externalLdap.auth' | tr }}</span>
|
|
</div>
|
|
<div class="col-xs-6 text-right">
|
|
<span>{{ externalLdap.currentConfig.bindDn ? 'Yes' : 'No' }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row" ng-show="externalLdap.currentConfig.provider !== 'noop'">
|
|
<div class="col-xs-6">
|
|
<span class="text-muted">{{ 'users.externalLdap.autocreateUsersOnLogin' | tr }}</span>
|
|
</div>
|
|
<div class="col-xs-6 text-right">
|
|
<span>{{ externalLdap.currentConfig.autoCreate ? 'Yes' : 'No' }}</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<br/>
|
|
<div class="col-md-12" style="margin-bottom: 10px;">
|
|
<div ng-show="externalLdap.syncBusy" class="progress progress-striped active animateMe">
|
|
<div class="progress-bar progress-bar-success" role="progressbar" style="width: {{ externalLdap.percent }}%"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<p ng-show="externalLdap.syncBusy">{{ externalLdap.message }}</p>
|
|
<p ng-hide="externalLdap.syncBusy">
|
|
<div class="has-error" ng-show="!externalLdap.active">{{ externalLdap.errorMessage }}</div>
|
|
</p>
|
|
</div>
|
|
|
|
<div class="col-md-6 text-right">
|
|
<button class="btn btn-primary pull-right" ng-click="externalLdap.show()">{{ 'users.externalLdap.configureAction' | tr }}</button>
|
|
<button class="btn btn-success pull-right" ng-disabled="externalLdap.currentConfig.provider === 'noop'" ng-click="externalLdap.sync()"><i class="fa fa-circle-notch fa-spin" ng-show="externalLdap.syncBusy"></i> {{ 'users.externalLdap.syncAction' | tr }}</button>
|
|
<a class="btn btn-primary pull-right" ng-show="externalLdap.taskId" ng-href="/frontend/logs.html?taskId={{ externalLdap.taskId }}" target="_blank">{{ 'users.externalLdap.showLogsAction' | tr }}</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="text-left section-header" ng-show="user.isAtLeastAdmin">
|
|
<h3>{{ 'users.exposedLdap.title' | tr }}</h3>
|
|
</div>
|
|
|
|
<div class="card card-large" ng-show="user.isAtLeastAdmin">
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div>{{ 'users.exposedLdap.description' | tr }}</div>
|
|
|
|
<br/>
|
|
|
|
<form name="userDirectoryConfigForm" role="form" novalidate ng-submit="userDirectoryConfig.submit()" autocomplete="off">
|
|
<fieldset>
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" ng-model="userDirectoryConfig.enabled" ng-disabled="userDirectoryConfig.busy"> {{ 'users.exposedLdap.enabled' | tr }} <sup><a ng-href="https://docs.cloudron.io/user-management/#directory-server" class="help" target="_blank"><i class="fa fa-question-circle"></i></a></sup>
|
|
</label>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">{{ 'users.exposedLdap.secret.url' | tr }}</label>
|
|
<div class="input-group">
|
|
<input type="text" id="userDirectoryUrlInput" ng-value="'ldaps://' + config.adminFqdn + ':636'" readonly name="userDirectoryUrl" class="form-control"/>
|
|
<span class="input-group-btn">
|
|
<button class="btn btn-default" type="button" id="userDirectoryUrlClipboardButton" data-clipboard-target="#userDirectoryUrlInput"><i class="fa fa-clipboard"></i></button>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">{{ 'users.exposedLdap.secret.label' | tr }}</label>
|
|
<p class="small" ng-bind-html=" 'users.exposedLdap.secret.description' | tr:{ userDN: 'cn=admin,ou=system,dc=cloudron' }"></p>
|
|
<input type="password" ng-model="userDirectoryConfig.secret" ng-disabled="!userDirectoryConfig.enabled || userDirectoryConfig.busy" name="userDirectorySecret" class="form-control" ng-class="{ 'has-error': !userDirectoryConfigForm.secret.$dirty && userDirectoryConfig.error.secret }" password-reveal/>
|
|
<div class="has-error" ng-show="userDirectoryConfig.error.secret">{{ userDirectoryConfig.error.secret }}</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">{{ 'users.exposedLdap.ipRestriction.label' | tr }}</label>
|
|
<p class="small">{{ 'users.exposedLdap.ipRestriction.description' | tr }}</p>
|
|
<textarea ng-model="userDirectoryConfig.allowlist" ng-disabled="!userDirectoryConfig.enabled || userDirectoryConfig.busy" placeholder="{{ 'users.exposedLdap.ipRestriction.placeholder' | tr }}" name="allowlist" class="form-control" ng-class="{ 'has-error': !userDirectoryConfigForm.allowlist.$dirty && userDirectoryConfig.error.allowlist }" rows="4"></textarea>
|
|
<div class="has-error" ng-show="userDirectoryConfig.error.allowlist">{{ userDirectoryConfig.error.allowlist }}</div>
|
|
</div>
|
|
</fieldset>
|
|
</form>
|
|
|
|
<br/>
|
|
|
|
<div>
|
|
<span class="has-error" ng-show="userDirectoryConfig.error.generic">{{ userDirectoryConfig.error.generic }}</span>
|
|
|
|
<button class="btn btn-outline btn-primary pull-right" ng-click="userDirectoryConfig.submit()" ng-disabled="!userDirectoryConfigForm.$dirty || userDirectoryConfig.busy">
|
|
<i class="fa fa-circle-notch fa-spin" ng-show="userDirectoryConfig.busy"></i> {{ 'users.settings.saveAction' | tr }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="text-left section-header" ng-show="user.isAtLeastAdmin">
|
|
<h3>{{ 'oidc.title' | tr }}</h3>
|
|
</div>
|
|
|
|
<div class="card card-large" ng-show="user.isAtLeastAdmin">
|
|
<div class="row">
|
|
<div class="col-md-12" style="line-height: 34px;">
|
|
{{ 'oidc.description' | tr }}
|
|
<a href="/#/oidc" class="btn btn-outline btn-primary pull-right">{{ 'main.settings' | tr }}</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|