SEBSERV-131 implementation
This commit is contained in:
		
							parent
							
								
									ab56ce3cc4
								
							
						
					
					
						commit
						97f174d740
					
				
					 7 changed files with 182 additions and 3 deletions
				
			
		|  | @ -157,6 +157,7 @@ public final class API { | ||||||
|     public static final String EXAM_INDICATOR_ENDPOINT = "/indicator"; |     public static final String EXAM_INDICATOR_ENDPOINT = "/indicator"; | ||||||
| 
 | 
 | ||||||
|     public static final String SEB_CLIENT_CONFIG_ENDPOINT = "/client_configuration"; |     public static final String SEB_CLIENT_CONFIG_ENDPOINT = "/client_configuration"; | ||||||
|  |     public static final String SEB_CLIENT_CONFIG_CREDENTIALS_PATH_SEGMENT = "/credentials"; | ||||||
|     public static final String SEB_CLIENT_CONFIG_DOWNLOAD_PATH_SEGMENT = "/download"; |     public static final String SEB_CLIENT_CONFIG_DOWNLOAD_PATH_SEGMENT = "/download"; | ||||||
| 
 | 
 | ||||||
|     public static final String CONFIGURATION_NODE_ENDPOINT = "/configuration-node"; |     public static final String CONFIGURATION_NODE_ENDPOINT = "/configuration-node"; | ||||||
|  |  | ||||||
|  | @ -8,20 +8,34 @@ | ||||||
| 
 | 
 | ||||||
| package ch.ethz.seb.sebserver.gbl.client; | package ch.ethz.seb.sebserver.gbl.client; | ||||||
| 
 | 
 | ||||||
|  | import com.fasterxml.jackson.annotation.JsonCreator; | ||||||
|  | import com.fasterxml.jackson.annotation.JsonIgnore; | ||||||
|  | import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||||||
|  | import com.fasterxml.jackson.annotation.JsonProperty; | ||||||
|  | 
 | ||||||
| /** Defines a simple data bean holding (encrypted) client credentials */ | /** Defines a simple data bean holding (encrypted) client credentials */ | ||||||
|  | @JsonIgnoreProperties(ignoreUnknown = true) | ||||||
| public final class ClientCredentials { | public final class ClientCredentials { | ||||||
| 
 | 
 | ||||||
|  |     public static final String ATTR_CLIENT_ID = "clientId"; | ||||||
|  |     public static final String ATTR_SECRET = "secret"; | ||||||
|  |     public static final String ATTR_ACCESS_TOKEN = "accessToken"; | ||||||
|  | 
 | ||||||
|     /** The client id or client name parameter */ |     /** The client id or client name parameter */ | ||||||
|  |     @JsonProperty(ATTR_CLIENT_ID) | ||||||
|     public final CharSequence clientId; |     public final CharSequence clientId; | ||||||
|     /** The client secret parameter */ |     /** The client secret parameter */ | ||||||
|  |     @JsonProperty(ATTR_SECRET) | ||||||
|     public final CharSequence secret; |     public final CharSequence secret; | ||||||
|     /** An client access token if supported */ |     /** An client access token if supported */ | ||||||
|  |     @JsonProperty(ATTR_ACCESS_TOKEN) | ||||||
|     public final CharSequence accessToken; |     public final CharSequence accessToken; | ||||||
| 
 | 
 | ||||||
|  |     @JsonCreator | ||||||
|     public ClientCredentials( |     public ClientCredentials( | ||||||
|             final CharSequence clientId, |             @JsonProperty(ATTR_CLIENT_ID) final CharSequence clientId, | ||||||
|             final CharSequence secret, |             @JsonProperty(ATTR_SECRET) final CharSequence secret, | ||||||
|             final CharSequence accessToken) { |             @JsonProperty(ATTR_ACCESS_TOKEN) final CharSequence accessToken) { | ||||||
| 
 | 
 | ||||||
|         this.clientId = clientId; |         this.clientId = clientId; | ||||||
|         this.secret = secret; |         this.secret = secret; | ||||||
|  | @ -35,26 +49,44 @@ public final class ClientCredentials { | ||||||
|         this(clientId, secret, null); |         this(clientId, secret, null); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public CharSequence getClientId() { | ||||||
|  |         return this.clientId; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public CharSequence getSecret() { | ||||||
|  |         return this.secret; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public CharSequence getAccessToken() { | ||||||
|  |         return this.accessToken; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @JsonIgnore | ||||||
|     public boolean hasClientId() { |     public boolean hasClientId() { | ||||||
|         return this.clientId != null && this.clientId.length() > 0; |         return this.clientId != null && this.clientId.length() > 0; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @JsonIgnore | ||||||
|     public boolean hasSecret() { |     public boolean hasSecret() { | ||||||
|         return this.secret != null && this.secret.length() > 0; |         return this.secret != null && this.secret.length() > 0; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @JsonIgnore | ||||||
|     public boolean hasAccessToken() { |     public boolean hasAccessToken() { | ||||||
|         return this.accessToken != null && this.accessToken.length() > 0; |         return this.accessToken != null && this.accessToken.length() > 0; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @JsonIgnore | ||||||
|     public String clientIdAsString() { |     public String clientIdAsString() { | ||||||
|         return hasClientId() ? this.clientId.toString() : null; |         return hasClientId() ? this.clientId.toString() : null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @JsonIgnore | ||||||
|     public String secretAsString() { |     public String secretAsString() { | ||||||
|         return hasSecret() ? this.secret.toString() : null; |         return hasSecret() ? this.secret.toString() : null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @JsonIgnore | ||||||
|     public String accessTokenAsString() { |     public String accessTokenAsString() { | ||||||
|         return hasAccessToken() ? this.accessToken.toString() : null; |         return hasAccessToken() ? this.accessToken.toString() : null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -532,6 +532,11 @@ public enum ActionDefinition { | ||||||
|             ImageIcon.DELETE, |             ImageIcon.DELETE, | ||||||
|             PageStateDefinitionImpl.SEB_CLIENT_CONFIG_LIST, |             PageStateDefinitionImpl.SEB_CLIENT_CONFIG_LIST, | ||||||
|             ActionCategory.FORM), |             ActionCategory.FORM), | ||||||
|  |     SEB_CLIENT_CONFIG_SHOW_CREDENTIALS( | ||||||
|  |             new LocTextKey("sebserver.clientconfig.action.credentials"), | ||||||
|  |             ImageIcon.SECURE, | ||||||
|  |             PageStateDefinitionImpl.SEB_CLIENT_CONFIG_VIEW, | ||||||
|  |             ActionCategory.FORM), | ||||||
| 
 | 
 | ||||||
|     SEB_EXAM_CONFIG_LIST( |     SEB_EXAM_CONFIG_LIST( | ||||||
|             new LocTextKey("sebserver.examconfig.action.list"), |             new LocTextKey("sebserver.examconfig.action.list"), | ||||||
|  |  | ||||||
|  | @ -9,6 +9,7 @@ | ||||||
| package ch.ethz.seb.sebserver.gui.content.configs; | package ch.ethz.seb.sebserver.gui.content.configs; | ||||||
| 
 | 
 | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
|  | import java.util.function.Function; | ||||||
| 
 | 
 | ||||||
| import org.apache.commons.lang3.BooleanUtils; | import org.apache.commons.lang3.BooleanUtils; | ||||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||||
|  | @ -27,6 +28,7 @@ import org.springframework.stereotype.Component; | ||||||
| import ch.ethz.seb.sebserver.gbl.Constants; | import ch.ethz.seb.sebserver.gbl.Constants; | ||||||
| import ch.ethz.seb.sebserver.gbl.api.API; | import ch.ethz.seb.sebserver.gbl.api.API; | ||||||
| import ch.ethz.seb.sebserver.gbl.api.EntityType; | import ch.ethz.seb.sebserver.gbl.api.EntityType; | ||||||
|  | import ch.ethz.seb.sebserver.gbl.client.ClientCredentials; | ||||||
| import ch.ethz.seb.sebserver.gbl.model.Domain; | import ch.ethz.seb.sebserver.gbl.model.Domain; | ||||||
| import ch.ethz.seb.sebserver.gbl.model.EntityKey; | import ch.ethz.seb.sebserver.gbl.model.EntityKey; | ||||||
| import ch.ethz.seb.sebserver.gbl.model.sebconfig.SEBClientConfig; | import ch.ethz.seb.sebserver.gbl.model.sebconfig.SEBClientConfig; | ||||||
|  | @ -44,6 +46,7 @@ import ch.ethz.seb.sebserver.gui.service.page.PageContext; | ||||||
| import ch.ethz.seb.sebserver.gui.service.page.PageMessageException; | import ch.ethz.seb.sebserver.gui.service.page.PageMessageException; | ||||||
| import ch.ethz.seb.sebserver.gui.service.page.PageService; | import ch.ethz.seb.sebserver.gui.service.page.PageService; | ||||||
| import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; | import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer; | ||||||
|  | import ch.ethz.seb.sebserver.gui.service.page.impl.ModalInputDialog; | ||||||
| import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction; | import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction; | ||||||
| import ch.ethz.seb.sebserver.gui.service.remote.download.DownloadService; | import ch.ethz.seb.sebserver.gui.service.remote.download.DownloadService; | ||||||
| import ch.ethz.seb.sebserver.gui.service.remote.download.SEBClientConfigDownload; | import ch.ethz.seb.sebserver.gui.service.remote.download.SEBClientConfigDownload; | ||||||
|  | @ -52,11 +55,13 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig. | ||||||
| import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.DeactivateClientConfig; | import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.DeactivateClientConfig; | ||||||
| import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.DeleteClientConfig; | import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.DeleteClientConfig; | ||||||
| import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.GetClientConfig; | import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.GetClientConfig; | ||||||
|  | import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.GetClientCredentials; | ||||||
| import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.NewClientConfig; | import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.NewClientConfig; | ||||||
| import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.SaveClientConfig; | import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig.SaveClientConfig; | ||||||
| import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; | import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser; | ||||||
| import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck; | import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser.EntityGrantCheck; | ||||||
| import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; | import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; | ||||||
|  | import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.CustomVariant; | ||||||
| 
 | 
 | ||||||
| @Lazy | @Lazy | ||||||
| @Component | @Component | ||||||
|  | @ -76,6 +81,15 @@ public class SEBClientConfigForm implements TemplateComposer { | ||||||
|     private static final LocTextKey FORM_UPDATE_TIME_TEXT_KEY = |     private static final LocTextKey FORM_UPDATE_TIME_TEXT_KEY = | ||||||
|             new LocTextKey("sebserver.clientconfig.form.update.time"); |             new LocTextKey("sebserver.clientconfig.form.update.time"); | ||||||
| 
 | 
 | ||||||
|  |     private static final LocTextKey CLIENT_CREDENTIALS_TITLE_TEXT_KEY = | ||||||
|  |             new LocTextKey("sebserver.clientconfig.form.credentials.title"); | ||||||
|  |     private static final LocTextKey CLIENT_CREDENTIALS_INFO_TEXT_KEY = | ||||||
|  |             new LocTextKey("sebserver.clientconfig.form.credentials.info"); | ||||||
|  |     private static final LocTextKey CLIENT_CREDENTIALS_NAME_TEXT_KEY = | ||||||
|  |             new LocTextKey("sebserver.clientconfig.form.credentials.name"); | ||||||
|  |     private static final LocTextKey CLIENT_CREDENTIALS_SECRET_TEXT_KEY = | ||||||
|  |             new LocTextKey("sebserver.clientconfig.form.credentials.secret"); | ||||||
|  | 
 | ||||||
|     private static final LocTextKey FORM_DATE_TEXT_KEY = |     private static final LocTextKey FORM_DATE_TEXT_KEY = | ||||||
|             new LocTextKey("sebserver.clientconfig.form.date"); |             new LocTextKey("sebserver.clientconfig.form.date"); | ||||||
|     private static final LocTextKey CLIENT_PURPOSE_TEXT_KEY = |     private static final LocTextKey CLIENT_PURPOSE_TEXT_KEY = | ||||||
|  | @ -210,6 +224,12 @@ public class SEBClientConfigForm implements TemplateComposer { | ||||||
|                 .withExec(this::deleteConnectionConfig) |                 .withExec(this::deleteConnectionConfig) | ||||||
|                 .publishIf(() -> modifyGrant && isReadonly) |                 .publishIf(() -> modifyGrant && isReadonly) | ||||||
| 
 | 
 | ||||||
|  |                 .newAction(ActionDefinition.SEB_CLIENT_CONFIG_SHOW_CREDENTIALS) | ||||||
|  |                 .withEntityKey(entityKey) | ||||||
|  |                 .withExec(getClientCredentialFunction(this.pageService, this.cryptor)) | ||||||
|  |                 .ignoreMoveAwayFromEdit() | ||||||
|  |                 .publishIf(() -> modifyGrant && isReadonly) | ||||||
|  | 
 | ||||||
|                 .newAction(ActionDefinition.SEB_CLIENT_CONFIG_EXPORT) |                 .newAction(ActionDefinition.SEB_CLIENT_CONFIG_EXPORT) | ||||||
|                 .withEntityKey(entityKey) |                 .withEntityKey(entityKey) | ||||||
|                 .withExec(action -> { |                 .withExec(action -> { | ||||||
|  | @ -558,6 +578,60 @@ public class SEBClientConfigForm implements TemplateComposer { | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public static Function<PageAction, PageAction> getClientCredentialFunction( | ||||||
|  |             final PageService pageService, | ||||||
|  |             final Cryptor cryptor) { | ||||||
|  | 
 | ||||||
|  |         final RestService restService = pageService.getResourceService().getRestService(); | ||||||
|  |         return action -> { | ||||||
|  | 
 | ||||||
|  |             final ClientCredentials credentials = restService | ||||||
|  |                     .getBuilder(GetClientCredentials.class) | ||||||
|  |                     .withURIVariable(API.PARAM_MODEL_ID, action.getEntityKey().modelId) | ||||||
|  |                     .call() | ||||||
|  |                     .getOrThrow(); | ||||||
|  | 
 | ||||||
|  |             final WidgetFactory widgetFactory = pageService.getWidgetFactory(); | ||||||
|  |             final ModalInputDialog<Void> dialog = new ModalInputDialog<>( | ||||||
|  |                     action.pageContext().getParent().getShell(), | ||||||
|  |                     widgetFactory); | ||||||
|  | 
 | ||||||
|  |             dialog.setDialogWidth(720); | ||||||
|  | 
 | ||||||
|  |             dialog.open( | ||||||
|  |                     CLIENT_CREDENTIALS_TITLE_TEXT_KEY, | ||||||
|  |                     action.pageContext(), | ||||||
|  |                     pc -> { | ||||||
|  | 
 | ||||||
|  |                         final Composite content = widgetFactory.defaultPageLayout( | ||||||
|  |                                 pc.getParent()); | ||||||
|  | 
 | ||||||
|  |                         widgetFactory.labelLocalized( | ||||||
|  |                                 content, | ||||||
|  |                                 CustomVariant.TEXT_H3, | ||||||
|  |                                 CLIENT_CREDENTIALS_INFO_TEXT_KEY); | ||||||
|  | 
 | ||||||
|  |                         pageService.formBuilder( | ||||||
|  |                                 action.pageContext().copyOf(content)) | ||||||
|  |                                 .readonly(true) | ||||||
|  |                                 .withDefaultSpanLabel(1) | ||||||
|  |                                 .withDefaultSpanInput(6) | ||||||
|  | 
 | ||||||
|  |                                 .addField(FormBuilder.text( | ||||||
|  |                                         "ClientId", | ||||||
|  |                                         CLIENT_CREDENTIALS_NAME_TEXT_KEY, | ||||||
|  |                                         credentials.clientIdAsString())) | ||||||
|  | 
 | ||||||
|  |                                 .addField(FormBuilder.password( | ||||||
|  |                                         "ClientSecret", | ||||||
|  |                                         CLIENT_CREDENTIALS_SECRET_TEXT_KEY, | ||||||
|  |                                         cryptor.decrypt(credentials.secret).getOrThrow())) | ||||||
|  |                                 .build(); | ||||||
|  |                     }); | ||||||
|  |             return action; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     private static final class FormHandleAnchor { |     private static final class FormHandleAnchor { | ||||||
| 
 | 
 | ||||||
|         FormHandle<SEBClientConfig> formHandle; |         FormHandle<SEBClientConfig> formHandle; | ||||||
|  |  | ||||||
|  | @ -0,0 +1,41 @@ | ||||||
|  | /* | ||||||
|  |  * Copyright (c) 2022 ETH Zürich, Educational Development and Technology (LET) | ||||||
|  |  * | ||||||
|  |  * This Source Code Form is subject to the terms of the Mozilla Public | ||||||
|  |  * License, v. 2.0. If a copy of the MPL was not distributed with this | ||||||
|  |  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.clientconfig; | ||||||
|  | 
 | ||||||
|  | import org.springframework.context.annotation.Lazy; | ||||||
|  | import org.springframework.http.HttpMethod; | ||||||
|  | import org.springframework.http.MediaType; | ||||||
|  | import org.springframework.stereotype.Component; | ||||||
|  | 
 | ||||||
|  | import com.fasterxml.jackson.core.type.TypeReference; | ||||||
|  | 
 | ||||||
|  | import ch.ethz.seb.sebserver.gbl.api.API; | ||||||
|  | import ch.ethz.seb.sebserver.gbl.client.ClientCredentials; | ||||||
|  | import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; | ||||||
|  | import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; | ||||||
|  | 
 | ||||||
|  | @Lazy | ||||||
|  | @Component | ||||||
|  | @GuiProfile | ||||||
|  | public class GetClientCredentials extends RestCall<ClientCredentials> { | ||||||
|  | 
 | ||||||
|  |     public GetClientCredentials() { | ||||||
|  |         super(new TypeKey<>( | ||||||
|  |                 CallType.GET_SINGLE, | ||||||
|  |                 null, | ||||||
|  |                 new TypeReference<ClientCredentials>() { | ||||||
|  |                 }), | ||||||
|  |                 HttpMethod.GET, | ||||||
|  |                 MediaType.APPLICATION_FORM_URLENCODED, | ||||||
|  |                 API.SEB_CLIENT_CONFIG_ENDPOINT | ||||||
|  |                         + API.SEB_CLIENT_CONFIG_CREDENTIALS_PATH_SEGMENT | ||||||
|  |                         + API.MODEL_ID_VAR_PATH_SEGMENT); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -37,6 +37,7 @@ import ch.ethz.seb.sebserver.gbl.Constants; | ||||||
| import ch.ethz.seb.sebserver.gbl.api.API; | import ch.ethz.seb.sebserver.gbl.api.API; | ||||||
| import ch.ethz.seb.sebserver.gbl.api.APIMessage; | import ch.ethz.seb.sebserver.gbl.api.APIMessage; | ||||||
| import ch.ethz.seb.sebserver.gbl.api.POSTMapper; | import ch.ethz.seb.sebserver.gbl.api.POSTMapper; | ||||||
|  | import ch.ethz.seb.sebserver.gbl.client.ClientCredentials; | ||||||
| import ch.ethz.seb.sebserver.gbl.model.Domain; | import ch.ethz.seb.sebserver.gbl.model.Domain; | ||||||
| import ch.ethz.seb.sebserver.gbl.model.Domain.EXAM; | import ch.ethz.seb.sebserver.gbl.model.Domain.EXAM; | ||||||
| import ch.ethz.seb.sebserver.gbl.model.Entity; | import ch.ethz.seb.sebserver.gbl.model.Entity; | ||||||
|  | @ -81,6 +82,25 @@ public class SEBClientConfigController extends ActivatableEntityController<SEBCl | ||||||
|         this.sebClientConfigService = sebClientConfigService; |         this.sebClientConfigService = sebClientConfigService; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     @RequestMapping( | ||||||
|  |             path = API.SEB_CLIENT_CONFIG_CREDENTIALS_PATH_SEGMENT + API.MODEL_ID_VAR_PATH_SEGMENT, | ||||||
|  |             method = RequestMethod.GET, | ||||||
|  |             produces = MediaType.APPLICATION_JSON_VALUE) | ||||||
|  |     public ClientCredentials getClientCredentials( | ||||||
|  |             @PathVariable final String modelId, | ||||||
|  |             @RequestParam( | ||||||
|  |                     name = Entity.FILTER_ATTR_INSTITUTION, | ||||||
|  |                     required = true, | ||||||
|  |                     defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId) { | ||||||
|  | 
 | ||||||
|  |         checkReadPrivilege(institutionId); | ||||||
|  | 
 | ||||||
|  |         return this.entityDAO.byModelId(modelId) | ||||||
|  |                 .flatMap(this.authorization::checkWrite) | ||||||
|  |                 .flatMap(config -> ((SEBClientConfigDAO) this.entityDAO).getSEBClientCredentials(modelId)) | ||||||
|  |                 .getOrThrow(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @RequestMapping( |     @RequestMapping( | ||||||
|             path = API.SEB_CLIENT_CONFIG_DOWNLOAD_PATH_SEGMENT + API.MODEL_ID_VAR_PATH_SEGMENT, |             path = API.SEB_CLIENT_CONFIG_DOWNLOAD_PATH_SEGMENT + API.MODEL_ID_VAR_PATH_SEGMENT, | ||||||
|             method = RequestMethod.GET, |             method = RequestMethod.GET, | ||||||
|  |  | ||||||
|  | @ -810,6 +810,11 @@ sebserver.clientconfig.form.certificate.tooltip=Choose identity certificate to b | ||||||
| sebserver.clientconfig.form.type.async=Use asymmetric-only encryption | sebserver.clientconfig.form.type.async=Use asymmetric-only encryption | ||||||
| sebserver.clientconfig.form.type.async.tooltip=Use old asymmetric-only encryption (for SEB < 2.2) | sebserver.clientconfig.form.type.async.tooltip=Use old asymmetric-only encryption (for SEB < 2.2) | ||||||
| 
 | 
 | ||||||
|  | sebserver.clientconfig.form.credentials.title=Client Credentials of Connection Configuration | ||||||
|  | sebserver.clientconfig.form.credentials.info=A SEB client that loads this connection configuration<br/>uses the following credentials to securely connect to the SEB Server. | ||||||
|  | sebserver.clientconfig.form.credentials.name=Client Id | ||||||
|  | sebserver.clientconfig.form.credentials.secret=Secret | ||||||
|  | 
 | ||||||
| sebserver.clientconfig.config.purpose.START_EXAM=Starting an Exam | sebserver.clientconfig.config.purpose.START_EXAM=Starting an Exam | ||||||
| sebserver.clientconfig.config.purpose.START_EXAM.tooltip=If the connection configuration is loaded via a SEB-Link, the local configuration will not be overwritten. | sebserver.clientconfig.config.purpose.START_EXAM.tooltip=If the connection configuration is loaded via a SEB-Link, the local configuration will not be overwritten. | ||||||
| sebserver.clientconfig.config.purpose.CONFIGURE_CLIENT=Configure a Client | sebserver.clientconfig.config.purpose.CONFIGURE_CLIENT=Configure a Client | ||||||
|  | @ -820,6 +825,7 @@ sebserver.clientconfig.action.list.view=View Connection Configuration | ||||||
| sebserver.clientconfig.action.list.modify=Edit Connection Configuration | sebserver.clientconfig.action.list.modify=Edit Connection Configuration | ||||||
| sebserver.clientconfig.action.modify=Edit Connection Configuration | sebserver.clientconfig.action.modify=Edit Connection Configuration | ||||||
| sebserver.clientconfig.action.save=Save Connection Configuration | sebserver.clientconfig.action.save=Save Connection Configuration | ||||||
|  | sebserver.clientconfig.action.credentials=Show Client Credentials | ||||||
| sebserver.clientconfig.action.activate=Activate Connection Configuration | sebserver.clientconfig.action.activate=Activate Connection Configuration | ||||||
| sebserver.clientconfig.action.deactivate=Deactivate Connection Configuration | sebserver.clientconfig.action.deactivate=Deactivate Connection Configuration | ||||||
| sebserver.clientconfig.action.export=Export Connection Configuration | sebserver.clientconfig.action.export=Export Connection Configuration | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 anhefti
						anhefti