SEBSERV-135 - gui implementation
This commit is contained in:
parent
ab8ac01e05
commit
18dce53170
19 changed files with 456 additions and 76 deletions
|
@ -202,5 +202,6 @@ public final class API {
|
|||
public static final String CERTIFICATE_ALIAS = "alias";
|
||||
public static final String CERTIFICATE_FILE_TYPE = "fileType";
|
||||
public static final String CERTIFICATE_PASSWORD_ATTR_NAME = "certPassword";
|
||||
public static final String CERTIFICATE_ALIAS_VAR_PATH_SEGMENT = "/{" + CERTIFICATE_ALIAS + "}";
|
||||
|
||||
}
|
||||
|
|
|
@ -20,17 +20,17 @@ import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
|||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class CertificateData implements Entity {
|
||||
public class CertificateInfo implements Entity {
|
||||
|
||||
public static enum CertificateType {
|
||||
UNKNOWN,
|
||||
SSL_TLS,
|
||||
CA,
|
||||
IDENTITY
|
||||
DIGITAL_SIGNATURE,
|
||||
DATA_ENCIPHERMENT,
|
||||
KEY_CERT_SIGN
|
||||
}
|
||||
|
||||
public static enum CertificateFileType {
|
||||
PEM("pem", "crt"),
|
||||
PEM("pem", "crt", "cer"),
|
||||
PKCS12("p12", "pfx");
|
||||
|
||||
private String[] extentions;
|
||||
|
@ -61,22 +61,17 @@ public class CertificateData implements Entity {
|
|||
@JsonProperty(ATTR_CERT_TYPE)
|
||||
public final EnumSet<CertificateType> types;
|
||||
|
||||
@JsonProperty(ATTR_CERT_BASE_64)
|
||||
public final String certBase64;
|
||||
|
||||
@JsonCreator
|
||||
public CertificateData(
|
||||
public CertificateInfo(
|
||||
@JsonProperty(ATTR_ALIAS) final String alias,
|
||||
@JsonProperty(ATTR_ALIAS) final DateTime validityFrom,
|
||||
@JsonProperty(ATTR_ALIAS) final DateTime validityTo,
|
||||
@JsonProperty(ATTR_CERT_TYPE) final EnumSet<CertificateType> types,
|
||||
@JsonProperty(ATTR_CERT_BASE_64) final String certBase64) {
|
||||
@JsonProperty(ATTR_CERT_TYPE) final EnumSet<CertificateType> types) {
|
||||
|
||||
this.alias = alias;
|
||||
this.validityFrom = validityFrom;
|
||||
this.validityTo = validityTo;
|
||||
this.types = types;
|
||||
this.certBase64 = certBase64;
|
||||
}
|
||||
|
||||
public String getAlias() {
|
||||
|
@ -95,10 +90,6 @@ public class CertificateData implements Entity {
|
|||
return this.types;
|
||||
}
|
||||
|
||||
public String getCertBase64() {
|
||||
return this.certBase64;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getModelId() {
|
||||
return this.alias;
|
||||
|
@ -130,7 +121,7 @@ public class CertificateData implements Entity {
|
|||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
final CertificateData other = (CertificateData) obj;
|
||||
final CertificateInfo other = (CertificateInfo) obj;
|
||||
if (this.alias == null) {
|
||||
if (other.alias != null)
|
||||
return false;
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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.content;
|
||||
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
|
||||
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
|
||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||
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.remote.webservice.api.RestService;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.seb.cert.GetCertificatePage;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition;
|
||||
import ch.ethz.seb.sebserver.gui.table.ColumnDefinition.TableFilterAttribute;
|
||||
import ch.ethz.seb.sebserver.gui.table.EntityTable;
|
||||
import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class CertificateList implements TemplateComposer {
|
||||
|
||||
private static final LocTextKey EMPTY_LIST_TEXT_KEY =
|
||||
new LocTextKey("sebserver.certificate.list.empty");
|
||||
private static final LocTextKey TITLE_TEXT_KEY =
|
||||
new LocTextKey("sebserver.certificate.list.title");
|
||||
private static final LocTextKey ALIAS_TEXT_KEY =
|
||||
new LocTextKey("sebserver.certificate.list.column.alias");
|
||||
private static final LocTextKey VALID_FROM_KEY =
|
||||
new LocTextKey("sebserver.certificate.list.column.validFrom");
|
||||
private static final LocTextKey VALID_TO_KEY =
|
||||
new LocTextKey("sebserver.certificate.list.column.validTo");
|
||||
private static final LocTextKey TYPE_TEXT_KEY =
|
||||
new LocTextKey("sebserver.certificate.list.column.type");
|
||||
|
||||
private final TableFilterAttribute aliasFilter = new TableFilterAttribute(
|
||||
CriteriaType.TEXT,
|
||||
CertificateInfo.FILTER_ATTR_ALIAS);
|
||||
|
||||
private final PageService pageService;
|
||||
private final RestService restService;
|
||||
private final CurrentUser currentUser;
|
||||
private final int pageSize;
|
||||
|
||||
protected CertificateList(
|
||||
final PageService pageService,
|
||||
@Value("${sebserver.gui.list.page.size:20}") final Integer pageSize) {
|
||||
|
||||
this.pageService = pageService;
|
||||
this.restService = pageService.getRestService();
|
||||
this.currentUser = pageService.getCurrentUser();
|
||||
this.pageSize = pageSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compose(final PageContext pageContext) {
|
||||
final Composite content = this.pageService
|
||||
.getWidgetFactory()
|
||||
.defaultPageLayout(
|
||||
pageContext.getParent(),
|
||||
TITLE_TEXT_KEY);
|
||||
|
||||
// table
|
||||
final EntityTable<CertificateInfo> table =
|
||||
this.pageService.entityTableBuilder(this.restService.getRestCall(GetCertificatePage.class))
|
||||
.withEmptyMessage(EMPTY_LIST_TEXT_KEY)
|
||||
.withPaging(this.pageSize)
|
||||
|
||||
.withColumn(new ColumnDefinition<>(
|
||||
CertificateInfo.ATTR_ALIAS,
|
||||
ALIAS_TEXT_KEY,
|
||||
CertificateInfo::getAlias)
|
||||
.sortable()
|
||||
.withFilter(this.aliasFilter))
|
||||
|
||||
.withColumn(new ColumnDefinition<>(
|
||||
CertificateInfo.ATTR_VALIDITY_FROM,
|
||||
VALID_FROM_KEY,
|
||||
CertificateInfo::getValidityFrom)
|
||||
.sortable())
|
||||
|
||||
.withColumn(new ColumnDefinition<>(
|
||||
CertificateInfo.ATTR_VALIDITY_TO,
|
||||
VALID_TO_KEY,
|
||||
CertificateInfo::getValidityTo)
|
||||
.sortable())
|
||||
|
||||
.withColumn(new ColumnDefinition<>(
|
||||
CertificateInfo.ATTR_CERT_TYPE,
|
||||
TYPE_TEXT_KEY,
|
||||
this::getTypeInfo))
|
||||
|
||||
.withSelectionListener(this.pageService.getSelectionPublisher(
|
||||
pageContext,
|
||||
ActionDefinition.SEB_CERTIFICATE_REMOVE))
|
||||
|
||||
.compose(pageContext.copyOf(content));
|
||||
}
|
||||
|
||||
private String getTypeInfo(final CertificateInfo certificateInfo) {
|
||||
final I18nSupport i18nSupport = this.pageService.getI18nSupport();
|
||||
//i18nSupport.getText("")
|
||||
|
||||
// TODO
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
|
@ -25,7 +25,8 @@ public enum ActionCategory {
|
|||
SEB_CONFIG_TEMPLATE_LIST(new LocTextKey("sebserver.configtemplate.list.actions"), 1),
|
||||
SEB_CONFIG_TEMPLATE_ATTRIBUTE_LIST(new LocTextKey("sebserver.configtemplate.attr.list.actions"), 1),
|
||||
RUNNING_EXAM_LIST(new LocTextKey("sebserver.monitoring.exam.list.actions"), 1),
|
||||
EXAM_MONITORING_NOTIFICATION_LIST(new LocTextKey("sebserver.monitoring.exam.connection.notificationlist.actions"),
|
||||
EXAM_MONITORING_NOTIFICATION_LIST(new LocTextKey(
|
||||
"sebserver.monitoring.exam.connection.notificationlist.actions"),
|
||||
1),
|
||||
CLIENT_EVENT_LIST(new LocTextKey("sebserver.monitoring.exam.connection.list.actions"), 1),
|
||||
LOGS_USER_ACTIVITY_LIST(new LocTextKey("sebserver.userlogs.list.actions"), 1),
|
||||
|
|
|
@ -612,6 +612,20 @@ public enum ActionDefinition {
|
|||
PageStateDefinitionImpl.SEB_EXAM_CONFIG_TEMPLATE_VIEW,
|
||||
ActionCategory.FORM),
|
||||
|
||||
SEB_CERTIFICATE_LIST(
|
||||
new LocTextKey("sebserver.certificate.action.list"),
|
||||
PageStateDefinitionImpl.SEB_CERTIFICATE_LIST),
|
||||
SEB_CERTIFICATE_IMPORT(
|
||||
new LocTextKey("sebserver.certificate.action.import"),
|
||||
ImageIcon.IMPORT,
|
||||
PageStateDefinitionImpl.SEB_CERTIFICATE_LIST,
|
||||
ActionCategory.FORM),
|
||||
SEB_CERTIFICATE_REMOVE(
|
||||
new LocTextKey("sebserver.certificate.action.remove"),
|
||||
ImageIcon.DELETE,
|
||||
PageStateDefinitionImpl.SEB_CERTIFICATE_LIST,
|
||||
ActionCategory.FORM),
|
||||
|
||||
RUNNING_EXAM_VIEW_LIST(
|
||||
new LocTextKey("sebserver.monitoring.action.list"),
|
||||
PageStateDefinitionImpl.MONITORING_RUNNING_EXAM_LIST),
|
||||
|
|
|
@ -229,6 +229,18 @@ public class ActivitiesPane implements TemplateComposer {
|
|||
.create());
|
||||
}
|
||||
|
||||
// Certificate management
|
||||
if (!isSupporterOnly) {
|
||||
final TreeItem examConfigTemplate = this.widgetFactory.treeItemLocalized(
|
||||
sebConfigs,
|
||||
ActivityDefinition.SEB_CERTIFICATE_MANAGEMENT.displayName);
|
||||
injectActivitySelection(
|
||||
examConfigTemplate,
|
||||
actionBuilder
|
||||
.newAction(ActionDefinition.SEB_CERTIFICATE_LIST)
|
||||
.create());
|
||||
}
|
||||
|
||||
sebConfigs.setExpanded(this.currentUser.get().hasAnyRole(UserRole.EXAM_ADMIN));
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ public enum ActivityDefinition implements Activity {
|
|||
SEB_CLIENT_CONFIG(new LocTextKey("sebserver.clientconfig.list.title")),
|
||||
SEB_EXAM_CONFIG(new LocTextKey("sebserver.examconfig.action.list")),
|
||||
SEB_EXAM_CONFIG_TEMPLATE(new LocTextKey("sebserver.configtemplate.action.list")),
|
||||
SEB_CERTIFICATE_MANAGEMENT(new LocTextKey("sebserver.certificate.action.list")),
|
||||
MONITORING(new LocTextKey("sebserver.overall.activity.title.monitoring")),
|
||||
MONITORING_EXAMS(new LocTextKey("sebserver.monitoring.action.list")),
|
||||
SEB_CLIENT_LOGS(new LocTextKey("sebserver.logs.activity.seblogs"));
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
package ch.ethz.seb.sebserver.gui.content.activity;
|
||||
|
||||
import ch.ethz.seb.sebserver.gui.content.CertificateList;
|
||||
import ch.ethz.seb.sebserver.gui.content.ConfigTemplateAttributeForm;
|
||||
import ch.ethz.seb.sebserver.gui.content.ConfigTemplateForm;
|
||||
import ch.ethz.seb.sebserver.gui.content.ConfigTemplateList;
|
||||
|
@ -25,8 +26,8 @@ import ch.ethz.seb.sebserver.gui.content.QuizLookupList;
|
|||
import ch.ethz.seb.sebserver.gui.content.SEBClientConfigForm;
|
||||
import ch.ethz.seb.sebserver.gui.content.SEBClientConfigList;
|
||||
import ch.ethz.seb.sebserver.gui.content.SEBClientEvents;
|
||||
import ch.ethz.seb.sebserver.gui.content.SEBExamConfigList;
|
||||
import ch.ethz.seb.sebserver.gui.content.SEBExamConfigForm;
|
||||
import ch.ethz.seb.sebserver.gui.content.SEBExamConfigList;
|
||||
import ch.ethz.seb.sebserver.gui.content.SEBSettingsForm;
|
||||
import ch.ethz.seb.sebserver.gui.content.UserAccountChangePasswordForm;
|
||||
import ch.ethz.seb.sebserver.gui.content.UserAccountForm;
|
||||
|
@ -80,6 +81,9 @@ public enum PageStateDefinitionImpl implements PageStateDefinition {
|
|||
ConfigTemplateAttributeForm.class,
|
||||
ActivityDefinition.SEB_EXAM_CONFIG_TEMPLATE),
|
||||
|
||||
SEB_CERTIFICATE_LIST(Type.LIST_VIEW, CertificateList.class,
|
||||
ActivityDefinition.SEB_CERTIFICATE_MANAGEMENT),
|
||||
|
||||
MONITORING_RUNNING_EXAM_LIST(Type.LIST_VIEW, MonitoringRunningExamList.class, ActivityDefinition.MONITORING_EXAMS),
|
||||
MONITORING_RUNNING_EXAM(Type.FORM_VIEW, MonitoringRunningExam.class, ActivityDefinition.MONITORING_EXAMS),
|
||||
MONITORING_CLIENT_CONNECTION(Type.FORM_VIEW, MonitoringClientConnection.class, ActivityDefinition.MONITORING_EXAMS),
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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.cert;
|
||||
|
||||
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.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class AddCertificate extends RestCall<CertificateInfo> {
|
||||
|
||||
public AddCertificate() {
|
||||
super(new TypeKey<>(
|
||||
CallType.UNDEFINED,
|
||||
EntityType.CERTIFICATE,
|
||||
new TypeReference<CertificateInfo>() {
|
||||
}),
|
||||
HttpMethod.POST,
|
||||
MediaType.APPLICATION_OCTET_STREAM,
|
||||
API.CERTIFICATE_ENDPOINT);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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.cert;
|
||||
|
||||
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.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class GetCertificate extends RestCall<CertificateInfo> {
|
||||
|
||||
public GetCertificate() {
|
||||
super(new TypeKey<>(
|
||||
CallType.GET_SINGLE,
|
||||
EntityType.CERTIFICATE,
|
||||
new TypeReference<CertificateInfo>() {
|
||||
}),
|
||||
HttpMethod.GET,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
API.CERTIFICATE_ENDPOINT + API.CERTIFICATE_ALIAS_VAR_PATH_SEGMENT);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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.cert;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
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.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.EntityName;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class GetCertificateNames extends RestCall<List<EntityName>> {
|
||||
|
||||
public GetCertificateNames() {
|
||||
super(new TypeKey<>(
|
||||
CallType.GET_NAMES,
|
||||
EntityType.CERTIFICATE,
|
||||
new TypeReference<List<EntityName>>() {
|
||||
}),
|
||||
HttpMethod.GET,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
API.CERTIFICATE_ENDPOINT + API.NAMES_PATH_SEGMENT);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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.cert;
|
||||
|
||||
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.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class GetCertificatePage extends RestCall<Page<CertificateInfo>> {
|
||||
|
||||
public GetCertificatePage() {
|
||||
super(new TypeKey<>(
|
||||
CallType.GET_PAGE,
|
||||
EntityType.CERTIFICATE,
|
||||
new TypeReference<Page<CertificateInfo>>() {
|
||||
}),
|
||||
HttpMethod.GET,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
API.CERTIFICATE_ENDPOINT);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2021 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.cert;
|
||||
|
||||
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.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||
|
||||
@Lazy
|
||||
@Component
|
||||
@GuiProfile
|
||||
public class RemoveCertificate extends RestCall<Void> {
|
||||
|
||||
public RemoveCertificate() {
|
||||
super(new TypeKey<>(
|
||||
CallType.GET_SINGLE,
|
||||
EntityType.CERTIFICATE,
|
||||
new TypeReference<>() {
|
||||
}),
|
||||
HttpMethod.GET,
|
||||
MediaType.APPLICATION_FORM_URLENCODED,
|
||||
API.CERTIFICATE_ENDPOINT + API.CERTIFICATE_ALIAS_VAR_PATH_SEGMENT);
|
||||
}
|
||||
|
||||
}
|
|
@ -10,14 +10,13 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.dao;
|
|||
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Base64;
|
||||
import java.util.EnumSet;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateData;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateData.CertificateType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo.CertificateType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Certificates;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import io.micrometer.core.instrument.util.StringUtils;
|
||||
|
@ -27,22 +26,21 @@ public interface CertificateDAO {
|
|||
|
||||
Result<Certificates> getCertificates(Long institutionId);
|
||||
|
||||
Result<CertificateData> addCertificate(Long institutionId, String alias, Certificate certificate);
|
||||
Result<CertificateInfo> addCertificate(Long institutionId, String alias, Certificate certificate);
|
||||
|
||||
Result<Certificates> removeCertificate(Long institutionId, String alias);
|
||||
|
||||
static Result<CertificateData> getDataFromCertificate(final Certificates certificates, final String alias) {
|
||||
static Result<CertificateInfo> getDataFromCertificate(final Certificates certificates, final String alias) {
|
||||
return Result.tryCatch(() -> {
|
||||
final X509Certificate certificate = (X509Certificate) certificates.keyStore.engineGetCertificate(alias);
|
||||
if (certificate != null) {
|
||||
|
||||
final X509Certificate cert = certificate;
|
||||
return new CertificateData(
|
||||
return new CertificateInfo(
|
||||
extractAlias(cert, alias),
|
||||
new DateTime(cert.getNotBefore()),
|
||||
new DateTime(cert.getNotAfter()),
|
||||
getTypes(cert),
|
||||
Base64.getEncoder().encodeToString(cert.getEncoded()));
|
||||
getTypes(cert));
|
||||
|
||||
} else {
|
||||
throw new NoSuchElementException("X509Certificate with alias: " + alias);
|
||||
|
@ -75,17 +73,17 @@ public interface CertificateDAO {
|
|||
|
||||
// digitalSignature
|
||||
if (keyUsage[0]) {
|
||||
result.add(CertificateType.SSL_TLS);
|
||||
result.add(CertificateType.DIGITAL_SIGNATURE);
|
||||
}
|
||||
|
||||
// dataEncipherment
|
||||
if (keyUsage[3]) {
|
||||
result.add(CertificateType.IDENTITY);
|
||||
result.add(CertificateType.DATA_ENCIPHERMENT);
|
||||
}
|
||||
|
||||
// keyCertSign
|
||||
if (keyUsage[5]) {
|
||||
result.add(CertificateType.CA);
|
||||
result.add(CertificateType.KEY_CERT_SIGN);
|
||||
}
|
||||
|
||||
if (result.isEmpty()) {
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||
|
||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateData;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Certificates;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Cryptor;
|
||||
|
@ -68,7 +68,7 @@ public class CertificateDAOImpl implements CertificateDAO {
|
|||
|
||||
@Override
|
||||
@Transactional
|
||||
public Result<CertificateData> addCertificate(
|
||||
public Result<CertificateInfo> addCertificate(
|
||||
final Long institutionId,
|
||||
final String alias,
|
||||
final Certificate certificate) {
|
||||
|
|
|
@ -14,22 +14,22 @@ import java.util.function.Predicate;
|
|||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateData;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateData.CertificateFileType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateData.CertificateType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo.CertificateFileType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo.CertificateType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Certificates;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
|
||||
|
||||
public interface CertificateService {
|
||||
|
||||
Result<CertificateData> getCertificateData(Long institutionId, String alias);
|
||||
Result<CertificateInfo> getCertificateInfo(Long institutionId, String alias);
|
||||
|
||||
Result<Collection<CertificateData>> getCertificateData(Long institutionId, FilterMap filterMap);
|
||||
Result<Collection<CertificateInfo>> getCertificateInfo(Long institutionId, FilterMap filterMap);
|
||||
|
||||
Result<Certificates> getCertificates(Long institutionId);
|
||||
|
||||
Result<CertificateData> addCertificate(
|
||||
Result<CertificateInfo> addCertificate(
|
||||
Long institutionId,
|
||||
CertificateFileType certificateFileType,
|
||||
String alias,
|
||||
|
@ -37,19 +37,21 @@ public interface CertificateService {
|
|||
|
||||
Result<Certificates> removeCertificate(Long institutionId, String alias);
|
||||
|
||||
Result<Collection<CertificateData>> toCertificateData(Certificates certificates);
|
||||
Result<Collection<CertificateInfo>> toCertificateInfo(Certificates certificates);
|
||||
|
||||
default Predicate<CertificateData> createFilter(final FilterMap filterMap) {
|
||||
final String aliasFilter = filterMap.getString(CertificateData.FILTER_ATTR_ALIAS);
|
||||
Result<String> getBase64Encoded(Long institutionId, String alias);
|
||||
|
||||
default Predicate<CertificateInfo> createFilter(final FilterMap filterMap) {
|
||||
final String aliasFilter = filterMap.getString(CertificateInfo.FILTER_ATTR_ALIAS);
|
||||
final CertificateType typeFilter = filterMap.getEnum(
|
||||
CertificateData.FILTER_ATTR_TYPE,
|
||||
CertificateInfo.FILTER_ATTR_TYPE,
|
||||
CertificateType.class);
|
||||
return certificateData -> {
|
||||
return certificateInfo -> {
|
||||
if (StringUtils.isNotBlank(aliasFilter) &&
|
||||
!certificateData.alias.contains(aliasFilter)) {
|
||||
!certificateInfo.alias.contains(aliasFilter)) {
|
||||
return false;
|
||||
}
|
||||
if (typeFilter != null && !certificateData.types.contains(typeFilter)) {
|
||||
if (typeFilter != null && !certificateInfo.types.contains(typeFilter)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,8 +9,11 @@
|
|||
package ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.impl;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Base64;
|
||||
import java.util.Collection;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -18,8 +21,8 @@ import java.util.stream.Collectors;
|
|||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateData;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateData.CertificateFileType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo.CertificateFileType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Certificates;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||
|
@ -39,7 +42,7 @@ public class CertificateServiceImpl implements CertificateService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Result<CertificateData> getCertificateData(final Long institutionId, final String alias) {
|
||||
public Result<CertificateInfo> getCertificateInfo(final Long institutionId, final String alias) {
|
||||
|
||||
return this.certificateDAO
|
||||
.getCertificates(institutionId)
|
||||
|
@ -47,7 +50,7 @@ public class CertificateServiceImpl implements CertificateService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Result<Collection<CertificateData>> getCertificateData(
|
||||
public Result<Collection<CertificateInfo>> getCertificateInfo(
|
||||
final Long institutionId,
|
||||
final FilterMap filterMap) {
|
||||
|
||||
|
@ -64,7 +67,7 @@ public class CertificateServiceImpl implements CertificateService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Result<CertificateData> addCertificate(
|
||||
public Result<CertificateInfo> addCertificate(
|
||||
final Long institutionId,
|
||||
final CertificateFileType certificateFileType,
|
||||
final String alias,
|
||||
|
@ -83,13 +86,29 @@ public class CertificateServiceImpl implements CertificateService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public Result<Collection<CertificateData>> toCertificateData(final Certificates certificates) {
|
||||
public Result<Collection<CertificateInfo>> toCertificateInfo(final Certificates certificates) {
|
||||
return Result.tryCatch(() -> getDataFromCertificates(certificates));
|
||||
}
|
||||
|
||||
private Collection<CertificateData> getDataFromCertificates(
|
||||
@Override
|
||||
public Result<String> getBase64Encoded(final Long institutionId, final String alias) {
|
||||
return this.certificateDAO
|
||||
.getCertificates(institutionId)
|
||||
.map(certs -> certs.keyStore.engineGetCertificate(alias))
|
||||
.map(this::getBase64Encoded);
|
||||
}
|
||||
|
||||
private String getBase64Encoded(final Certificate cert) {
|
||||
try {
|
||||
return Base64.getEncoder().encodeToString(cert.getEncoded());
|
||||
} catch (final CertificateEncodingException e) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<CertificateInfo> getDataFromCertificates(
|
||||
final Certificates certificates,
|
||||
final Predicate<CertificateData> predicate) {
|
||||
final Predicate<CertificateInfo> predicate) {
|
||||
|
||||
return certificates.aliases
|
||||
.stream()
|
||||
|
@ -99,7 +118,7 @@ public class CertificateServiceImpl implements CertificateService {
|
|||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private Collection<CertificateData> getDataFromCertificates(final Certificates certificates) {
|
||||
private Collection<CertificateInfo> getDataFromCertificates(final Certificates certificates) {
|
||||
return getDataFromCertificates(certificates, data -> true);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,9 +39,8 @@ import ch.ethz.seb.sebserver.gbl.model.Entity;
|
|||
import ch.ethz.seb.sebserver.gbl.model.EntityName;
|
||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||
import ch.ethz.seb.sebserver.gbl.model.PageSortOrder;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateData;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateData.CertificateFileType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.Certificates;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo;
|
||||
import ch.ethz.seb.sebserver.gbl.model.sebconfig.CertificateInfo.CertificateFileType;
|
||||
import ch.ethz.seb.sebserver.gbl.model.user.UserLogActivityType;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService;
|
||||
|
@ -117,7 +116,7 @@ public class CertificateController {
|
|||
method = RequestMethod.GET,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public Page<CertificateData> getPage(
|
||||
public Page<CertificateInfo> getPage(
|
||||
@RequestParam(
|
||||
name = API.PARAM_INSTITUTION_ID,
|
||||
required = true,
|
||||
|
@ -131,8 +130,8 @@ public class CertificateController {
|
|||
checkReadPrivilege(institutionId);
|
||||
|
||||
final FilterMap filterMap = new FilterMap(allRequestParams, request.getQueryString());
|
||||
final Collection<CertificateData> certificates = this.certificateService
|
||||
.getCertificateData(institutionId, filterMap)
|
||||
final Collection<CertificateInfo> certificates = this.certificateService
|
||||
.getCertificateInfo(institutionId, filterMap)
|
||||
.getOrThrow();
|
||||
|
||||
return this.paginationService.buildPageFromList(
|
||||
|
@ -160,7 +159,7 @@ public class CertificateController {
|
|||
checkReadPrivilege(institutionId);
|
||||
|
||||
return this.certificateService
|
||||
.getCertificateData(
|
||||
.getCertificateInfo(
|
||||
institutionId,
|
||||
new FilterMap(allRequestParams, request.getQueryString()))
|
||||
.getOrThrow()
|
||||
|
@ -170,19 +169,19 @@ public class CertificateController {
|
|||
}
|
||||
|
||||
@RequestMapping(
|
||||
path = API.MODEL_ID_VAR_PATH_SEGMENT,
|
||||
path = API.CERTIFICATE_ALIAS_VAR_PATH_SEGMENT,
|
||||
method = RequestMethod.GET,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public CertificateData getBy(
|
||||
public CertificateInfo getAlias(
|
||||
@RequestParam(
|
||||
name = API.PARAM_INSTITUTION_ID,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@PathVariable final String modelId) {
|
||||
@PathVariable final String alias) {
|
||||
|
||||
return this.certificateService
|
||||
.getCertificateData(institutionId, modelId)
|
||||
.getCertificateInfo(institutionId, alias)
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
|
@ -190,7 +189,7 @@ public class CertificateController {
|
|||
method = RequestMethod.POST,
|
||||
consumes = MediaType.APPLICATION_OCTET_STREAM_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public Certificates loadCertificate(
|
||||
public CertificateInfo loadCertificate(
|
||||
@RequestParam(
|
||||
name = API.PARAM_INSTITUTION_ID,
|
||||
required = true,
|
||||
|
@ -212,8 +211,7 @@ public class CertificateController {
|
|||
|
||||
inputStream = new BufferedInputStream(request.getInputStream());
|
||||
return this.certificateService.addCertificate(institutionId, certificateFileType, alias, inputStream)
|
||||
.map(certData -> this.userActivityLogDAO.log(UserLogActivityType.IMPORT, certData))
|
||||
.flatMap(certData -> this.certificateService.getCertificates(institutionId))
|
||||
.flatMap(certData -> this.userActivityLogDAO.log(UserLogActivityType.IMPORT, certData))
|
||||
.getOrThrow();
|
||||
|
||||
} catch (final Exception e) {
|
||||
|
@ -226,21 +224,20 @@ public class CertificateController {
|
|||
}
|
||||
|
||||
@RequestMapping(
|
||||
path = API.CERTIFICATE_ALIAS_VAR_PATH_SEGMENT,
|
||||
method = RequestMethod.DELETE,
|
||||
consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE,
|
||||
produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public Certificates deleteCertificate(
|
||||
public void deleteCertificate(
|
||||
@RequestParam(
|
||||
name = API.PARAM_INSTITUTION_ID,
|
||||
required = true,
|
||||
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||
@RequestHeader(
|
||||
name = API.CERTIFICATE_ALIAS,
|
||||
required = true) final String alias) {
|
||||
@PathVariable final String alias) {
|
||||
|
||||
this.checkWritePrivilege(institutionId);
|
||||
|
||||
return this.certificateService.removeCertificate(institutionId, alias)
|
||||
this.certificateService.removeCertificate(institutionId, alias)
|
||||
.getOrThrow();
|
||||
}
|
||||
|
||||
|
@ -258,15 +255,15 @@ public class CertificateController {
|
|||
institutionId);
|
||||
}
|
||||
|
||||
private static Function<Collection<CertificateData>, List<CertificateData>> pageSort(final String sort) {
|
||||
private static Function<Collection<CertificateInfo>, List<CertificateInfo>> pageSort(final String sort) {
|
||||
return certificates -> {
|
||||
final List<CertificateData> list = certificates.stream().collect(Collectors.toList());
|
||||
final List<CertificateInfo> list = certificates.stream().collect(Collectors.toList());
|
||||
if (StringUtils.isBlank(sort)) {
|
||||
return list;
|
||||
}
|
||||
|
||||
final String sortBy = PageSortOrder.decode(sort);
|
||||
if (sortBy.equals(CertificateData.FILTER_ATTR_ALIAS)) {
|
||||
if (sortBy.equals(CertificateInfo.FILTER_ATTR_ALIAS)) {
|
||||
list.sort(Comparator.comparing(cert -> cert.alias));
|
||||
}
|
||||
|
||||
|
|
|
@ -1533,6 +1533,21 @@ sebserver.configtemplate.attr.action.setdefault=Set Default Values
|
|||
sebserver.configtemplate.attr.action.template=View Configuration Template
|
||||
|
||||
|
||||
sebserver.certificate.action.list=Certificates
|
||||
sebserver.certificate.action.import=Import Certificate
|
||||
sebserver.certificate.action.remove=Remove Selected Certificates
|
||||
|
||||
sebserver.certificate.list.title=Certificates
|
||||
sebserver.certificate.list.column.alias=Alias
|
||||
sebserver.certificate.list.column.validFrom=Valid From
|
||||
sebserver.certificate.list.column.validTo=Valid To
|
||||
sebserver.certificate.list.column.type=Types
|
||||
sebserver.certificate.list.column.type.UNKNOWN=Unknown
|
||||
sebserver.certificate.list.column.type.DIGITAL_SIGNATURE=TLS/SSL
|
||||
sebserver.certificate.list.column.type.DATA_ENCIPHERMENT=Identity
|
||||
sebserver.certificate.list.column.type.KEY_CERT_SIGN=CA
|
||||
|
||||
|
||||
################################
|
||||
# Monitoring
|
||||
################################
|
||||
|
|
Loading…
Reference in a new issue