fixes code cleanup and docu

This commit is contained in:
anhefti 2019-06-06 13:29:25 +02:00
parent f53243e001
commit 4e4883b8b7
19 changed files with 169 additions and 34 deletions

View file

@ -49,21 +49,19 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
@GuiProfile @GuiProfile
public class ExamList implements TemplateComposer { public class ExamList implements TemplateComposer {
private final PageService pageService; private static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION =
private final ResourceService resourceService; new LocTextKey("sebserver.exam.list.action.no.modify.privilege");
private final int pageSize; private final static LocTextKey EMPTY_SELECTION_TEXT_KEY =
private final static LocTextKey emptySelectionTextKey =
new LocTextKey("sebserver.exam.info.pleaseSelect"); new LocTextKey("sebserver.exam.info.pleaseSelect");
private final static LocTextKey columnTitleLmsSetupKey = private final static LocTextKey COLUMN_TITLE_KEY =
new LocTextKey("sebserver.exam.list.column.lmssetup"); new LocTextKey("sebserver.exam.list.column.lmssetup");
private final static LocTextKey columnTitleNameKey = private final static LocTextKey COLUMN_TITLE_NAME_KEY =
new LocTextKey("sebserver.exam.list.column.name"); new LocTextKey("sebserver.exam.list.column.name");
private final static LocTextKey columnTitleTypeKey = private final static LocTextKey COLUMN_TITLE_TYPE_KEY =
new LocTextKey("sebserver.exam.list.column.type"); new LocTextKey("sebserver.exam.list.column.type");
private final static LocTextKey noModifyOfOutDatedExams = private final static LocTextKey NO_MODIFY_OF_OUT_DATED_EXAMS =
new LocTextKey("sebserver.exam.list.modify.out.dated"); new LocTextKey("sebserver.exam.list.modify.out.dated");
private final static LocTextKey emptyListTextKey = private final static LocTextKey EMPTY_LIST_TEXT_KEY =
new LocTextKey("sebserver.exam.list.empty"); new LocTextKey("sebserver.exam.list.empty");
private final TableFilterAttribute lmsFilter; private final TableFilterAttribute lmsFilter;
@ -72,6 +70,10 @@ public class ExamList implements TemplateComposer {
private final TableFilterAttribute startTimeFilter = private final TableFilterAttribute startTimeFilter =
new TableFilterAttribute(CriteriaType.DATE, QuizData.FILTER_ATTR_START_TIME); new TableFilterAttribute(CriteriaType.DATE, QuizData.FILTER_ATTR_START_TIME);
private final PageService pageService;
private final ResourceService resourceService;
private final int pageSize;
protected ExamList( protected ExamList(
final PageService pageService, final PageService pageService,
final ResourceService resourceService, final ResourceService resourceService,
@ -105,17 +107,17 @@ public class ExamList implements TemplateComposer {
// table // table
final EntityTable<Exam> table = final EntityTable<Exam> table =
this.pageService.entityTableBuilder(restService.getRestCall(GetExamPage.class)) this.pageService.entityTableBuilder(restService.getRestCall(GetExamPage.class))
.withEmptyMessage(emptyListTextKey) .withEmptyMessage(EMPTY_LIST_TEXT_KEY)
.withPaging(this.pageSize) .withPaging(this.pageSize)
.withColumn(new ColumnDefinition<>( .withColumn(new ColumnDefinition<>(
Domain.EXAM.ATTR_LMS_SETUP_ID, Domain.EXAM.ATTR_LMS_SETUP_ID,
columnTitleLmsSetupKey, COLUMN_TITLE_KEY,
examLmsSetupNameFunction(this.resourceService)) examLmsSetupNameFunction(this.resourceService))
.withFilter(this.lmsFilter) .withFilter(this.lmsFilter)
.sortable()) .sortable())
.withColumn(new ColumnDefinition<>( .withColumn(new ColumnDefinition<>(
QuizData.QUIZ_ATTR_NAME, QuizData.QUIZ_ATTR_NAME,
columnTitleNameKey, COLUMN_TITLE_NAME_KEY,
Exam::getName) Exam::getName)
.withFilter(this.nameFilter) .withFilter(this.nameFilter)
.sortable()) .sortable())
@ -129,7 +131,7 @@ public class ExamList implements TemplateComposer {
.sortable()) .sortable())
.withColumn(new ColumnDefinition<>( .withColumn(new ColumnDefinition<>(
Domain.EXAM.ATTR_TYPE, Domain.EXAM.ATTR_TYPE,
columnTitleTypeKey, COLUMN_TITLE_TYPE_KEY,
this::examTypeName) this::examTypeName)
.sortable()) .sortable())
.withDefaultAction(actionBuilder .withDefaultAction(actionBuilder
@ -142,17 +144,17 @@ public class ExamList implements TemplateComposer {
actionBuilder actionBuilder
.newAction(ActionDefinition.EXAM_IMPORT) .newAction(ActionDefinition.EXAM_IMPORT)
.publishIf(userGrant::im) // TODO iw instead of im? .publishIf(userGrant::im)
.newAction(ActionDefinition.EXAM_VIEW_FROM_LIST) .newAction(ActionDefinition.EXAM_VIEW_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, emptySelectionTextKey) .withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(table::hasAnyContent) .publishIf(table::hasAnyContent)
.newAction(ActionDefinition.EXAM_MODIFY_FROM_LIST) .newAction(ActionDefinition.EXAM_MODIFY_FROM_LIST)
.withSelect( .withSelect(
table::getSelection, table.getGrantedSelection(currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
action -> this.modifyExam(action, table), action -> this.modifyExam(action, table),
emptySelectionTextKey) EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> userGrant.im() && table.hasAnyContent()); .publishIf(() -> userGrant.im() && table.hasAnyContent());
} }
@ -163,7 +165,7 @@ public class ExamList implements TemplateComposer {
if (exam.startTime != null) { if (exam.startTime != null) {
final DateTime now = DateTime.now(DateTimeZone.UTC); final DateTime now = DateTime.now(DateTimeZone.UTC);
if (exam.startTime.isBefore(now)) { if (exam.startTime.isBefore(now)) {
throw new PageMessageException(noModifyOfOutDatedExams); throw new PageMessageException(NO_MODIFY_OF_OUT_DATED_EXAMS);
} }
} }

View file

@ -45,6 +45,8 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
@GuiProfile @GuiProfile
public class LmsSetupList implements TemplateComposer { public class LmsSetupList implements TemplateComposer {
private static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION =
new LocTextKey("sebserver.lmssetup.list.action.no.modify.privilege");
private static final LocTextKey EMPTY_SELECTION_TEXT_KEY = private static final LocTextKey EMPTY_SELECTION_TEXT_KEY =
new LocTextKey("sebserver.lmssetup.info.pleaseSelect"); new LocTextKey("sebserver.lmssetup.info.pleaseSelect");
private static final LocTextKey ACTIVITY_TEXT_KEY = private static final LocTextKey ACTIVITY_TEXT_KEY =
@ -151,7 +153,9 @@ public class LmsSetupList implements TemplateComposer {
.publishIf(() -> table.hasAnyContent()) .publishIf(() -> table.hasAnyContent())
.newAction(ActionDefinition.LMS_SETUP_MODIFY_FROM_LIST) .newAction(ActionDefinition.LMS_SETUP_MODIFY_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(
table.getGrantedSelection(currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> userGrant.im() && table.hasAnyContent()); .publishIf(() -> userGrant.im() && table.hasAnyContent());
} }

View file

@ -47,6 +47,8 @@ import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
@GuiProfile @GuiProfile
public class SebClientConfigList implements TemplateComposer { public class SebClientConfigList implements TemplateComposer {
private static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION =
new LocTextKey("sebserver.clientconfig.list.action.no.modify.privilege");
private static final LocTextKey EMPTY_LIST_TEXT_KEY = private static final LocTextKey EMPTY_LIST_TEXT_KEY =
new LocTextKey("sebserver.clientconfig.list.empty"); new LocTextKey("sebserver.clientconfig.list.empty");
private static final LocTextKey TITLE_TEXT_KEY = private static final LocTextKey TITLE_TEXT_KEY =
@ -155,7 +157,9 @@ public class SebClientConfigList implements TemplateComposer {
.publishIf(() -> table.hasAnyContent()) .publishIf(() -> table.hasAnyContent())
.newAction(ActionDefinition.SEB_CLIENT_CONFIG_MODIFY_FROM_LIST) .newAction(ActionDefinition.SEB_CLIENT_CONFIG_MODIFY_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(
table.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> clientConfigGrant.im() && table.hasAnyContent()); .publishIf(() -> clientConfigGrant.im() && table.hasAnyContent());
} }

View file

@ -41,6 +41,8 @@ import ch.ethz.seb.sebserver.gui.table.TableFilter.CriteriaType;
@GuiProfile @GuiProfile
public class SebExamConfigList implements TemplateComposer { public class SebExamConfigList implements TemplateComposer {
private static final LocTextKey NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION =
new LocTextKey("sebserver.examconfig.list.action.no.modify.privilege");
private static final LocTextKey EMPTY_LIST_TEXT_KEY = private static final LocTextKey EMPTY_LIST_TEXT_KEY =
new LocTextKey("sebserver.examconfig.list.empty"); new LocTextKey("sebserver.examconfig.list.empty");
private static final LocTextKey TITLE_TEXT_KEY = private static final LocTextKey TITLE_TEXT_KEY =
@ -148,11 +150,15 @@ public class SebExamConfigList implements TemplateComposer {
.publishIf(() -> table.hasAnyContent()) .publishIf(() -> table.hasAnyContent())
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_PROP_FROM_LIST) .newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_PROP_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(
table.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> examConfigGrant.im() && table.hasAnyContent()) .publishIf(() -> examConfigGrant.im() && table.hasAnyContent())
.newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_FROM_LIST) .newAction(ActionDefinition.SEB_EXAM_CONFIG_MODIFY_FROM_LIST)
.withSelect(table::getSelection, PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY) .withSelect(
table.getGrantedSelection(this.currentUser, NO_MODIFY_PRIVILEGE_ON_OTHER_INSTITUION),
PageAction::applySingleSelection, EMPTY_SELECTION_TEXT_KEY)
.publishIf(() -> examConfigGrant.im() && table.hasAnyContent()); .publishIf(() -> examConfigGrant.im() && table.hasAnyContent());
} }

View file

@ -13,7 +13,6 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Composite;
@ -90,10 +89,6 @@ public class PassworFieldBuilder implements InputFieldBuilder {
return; return;
} }
if (StringUtils.isBlank(pwd) && StringUtils.isBlank(confirm)) {
return;
}
if (!pwd.equals(confirm)) { if (!pwd.equals(confirm)) {
passwordInputField.showError(viewContext passwordInputField.showError(viewContext
.getI18nSupport() .getI18nSupport()

View file

@ -17,6 +17,8 @@ import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.eclipse.swt.SWT; import org.eclipse.swt.SWT;
@ -35,14 +37,17 @@ import org.slf4j.LoggerFactory;
import ch.ethz.seb.sebserver.gbl.Constants; import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gbl.model.Entity;
import ch.ethz.seb.sebserver.gbl.model.EntityKey; import ch.ethz.seb.sebserver.gbl.model.EntityKey;
import ch.ethz.seb.sebserver.gbl.model.GrantEntity;
import ch.ethz.seb.sebserver.gbl.model.Page; import ch.ethz.seb.sebserver.gbl.model.Page;
import ch.ethz.seb.sebserver.gbl.model.PageSortOrder; import ch.ethz.seb.sebserver.gbl.model.PageSortOrder;
import ch.ethz.seb.sebserver.gbl.util.Utils; import ch.ethz.seb.sebserver.gbl.util.Utils;
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport; 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.i18n.LocTextKey;
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.impl.PageAction; import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon; import ch.ethz.seb.sebserver.gui.widget.WidgetFactory.ImageIcon;
@ -257,6 +262,10 @@ public class EntityTable<ROW extends Entity> {
} }
public Set<EntityKey> getSelection() { public Set<EntityKey> getSelection() {
return getSelection(null);
}
public Set<EntityKey> getSelection(final Predicate<ROW> grantCheck) {
final TableItem[] selection = this.table.getSelection(); final TableItem[] selection = this.table.getSelection();
if (selection == null) { if (selection == null) {
return Collections.emptySet(); return Collections.emptySet();
@ -264,10 +273,27 @@ public class EntityTable<ROW extends Entity> {
return Arrays.asList(selection) return Arrays.asList(selection)
.stream() .stream()
.filter(item -> grantCheck == null || grantCheck.test(getRowData(item)))
.map(this::getRowDataId) .map(this::getRowDataId)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
public Supplier<Set<EntityKey>> getGrantedSelection(
final CurrentUser currentUser,
final LocTextKey denyMessage) {
return () -> getSelection(e -> {
if (!(e instanceof GrantEntity)) {
return true;
}
if (currentUser.entityGrantCheck((GrantEntity) e).m()) {
return true;
} else {
throw new PageMessageException(denyMessage);
}
});
}
private void createTableColumns() { private void createTableColumns() {
for (final ColumnDefinition<ROW> column : this.columns) { for (final ColumnDefinition<ROW> column : this.columns) {
final TableColumn tableColumn = this.widgetFactory.tableColumnLocalized( final TableColumn tableColumn = this.widgetFactory.tableColumnLocalized(

View file

@ -80,7 +80,7 @@ public class AuthorizationServiceImpl implements AuthorizationService {
// grants for seb client config // grants for seb client config
addPrivilege(EntityType.SEB_CLIENT_CONFIGURATION) addPrivilege(EntityType.SEB_CLIENT_CONFIGURATION)
.forRole(UserRole.SEB_SERVER_ADMIN) .forRole(UserRole.SEB_SERVER_ADMIN)
.withBasePrivilege(PrivilegeType.WRITE) .withBasePrivilege(PrivilegeType.READ)
.andForRole(UserRole.INSTITUTIONAL_ADMIN) .andForRole(UserRole.INSTITUTIONAL_ADMIN)
.withInstitutionalPrivilege(PrivilegeType.WRITE) .withInstitutionalPrivilege(PrivilegeType.WRITE)
.andForRole(UserRole.EXAM_ADMIN) .andForRole(UserRole.EXAM_ADMIN)

View file

@ -80,12 +80,21 @@ public interface BulkActionSupportDAO<T extends Entity> {
throw new UnsupportedOperationException("Unsupported Bulk Action: " + bulkAction); throw new UnsupportedOperationException("Unsupported Bulk Action: " + bulkAction);
} }
/** This creates a collection of Results refer the given entity keys.
*
* @param keys Collection of entity keys to create Results from
* @return a collection of Results refer the given entity keys. */
static Collection<Result<EntityKey>> transformResult(final Collection<EntityKey> keys) { static Collection<Result<EntityKey>> transformResult(final Collection<EntityKey> keys) {
return keys.stream() return keys.stream()
.map(key -> Result.of(key)) .map(key -> Result.of(key))
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
/** This creates a list of Result refer to a given error for all given EntityKey instances.
*
* @param error the error that shall be referred by created Result's
* @param all all entity keys to create error Result for
* @return List of Result refer to a given error for all given EntityKey instances */
static List<Result<EntityKey>> handleBulkActionError(final Throwable error, final Set<EntityKey> all) { static List<Result<EntityKey>> handleBulkActionError(final Throwable error, final Set<EntityKey> all) {
return all.stream() return all.stream()
.map(key -> Result.<EntityKey> ofError(new BulkActionEntityException(key))) .map(key -> Result.<EntityKey> ofError(new BulkActionEntityException(key)))
@ -97,7 +106,7 @@ public interface BulkActionSupportDAO<T extends Entity> {
* and applies the selection functions for each, collecting the resulting dependency EntityKeys * and applies the selection functions for each, collecting the resulting dependency EntityKeys
* into one Set of all dependency keys for all source keys * into one Set of all dependency keys for all source keys
* *
* *
* @param bulkAction The BulkAction that defines the source keys * @param bulkAction The BulkAction that defines the source keys
* @param selectionFunction a selection functions that gives all dependency keys for a given source key * @param selectionFunction a selection functions that gives all dependency keys for a given source key
* @return */ * @return */

View file

@ -15,6 +15,10 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
public interface ConfigurationAttributeDAO extends EntityDAO<ConfigurationAttribute, ConfigurationAttribute> { public interface ConfigurationAttributeDAO extends EntityDAO<ConfigurationAttribute, ConfigurationAttribute> {
/** Use this to get all ConfigurationAttribute that are root attributes and no child
* attributes (has no parent reference).
*
* @return Collection of all ConfigurationAttribute that are root attributes */
Result<Collection<ConfigurationAttribute>> getAllRootAttributes(); Result<Collection<ConfigurationAttribute>> getAllRootAttributes();
} }

View file

@ -20,6 +20,12 @@ public final class DAOLoggingSupport {
public static final Logger log = LoggerFactory.getLogger(DAOLoggingSupport.class); public static final Logger log = LoggerFactory.getLogger(DAOLoggingSupport.class);
/** Use this as a functional method on Result processing to
* log an error that is referenced by a given Result and skip further processing by
* using Result.skipOnError.
*
* @param result The given Result
* @return Stream of the results value or empty stream on error case */
public static <T> Stream<T> logAndSkipOnError(final Result<T> result) { public static <T> Stream<T> logAndSkipOnError(final Result<T> result) {
return Result.skipOnError( return Result.skipOnError(
result.onError(error -> log.error("Unexpected error. Object processing is skipped: ", error))); result.onError(error -> log.error("Unexpected error. Object processing is skipped: ", error)));

View file

@ -174,7 +174,7 @@ public interface EntityDAO<T extends Entity, M extends ModelIdAware> {
* This uses the EntityType defined by this instance to filter all EntityKey by the given type and * This uses the EntityType defined by this instance to filter all EntityKey by the given type and
* convert the matching EntityKey's to id's (PK's) * convert the matching EntityKey's to id's (PK's)
* *
* Use this if you need to transform a Collection of EntityKey into a extracted List of id's of a specified * Use this if you need to transform a Collection of EntityKey into a extracted Set of id's of a specified
* EntityType * EntityType
* *
* @param keys Collection of EntityKey of various types * @param keys Collection of EntityKey of various types
@ -198,6 +198,15 @@ public interface EntityDAO<T extends Entity, M extends ModelIdAware> {
} }
} }
/** Context based utility method to extract a set of id's (PK) from a collection of various EntityKey
* This uses the EntityType defined by this instance to filter all EntityKey by the given type and
* convert the matching EntityKey's to id's (PK's)
*
* Use this if you need to transform a Collection of EntityKey into a extracted List of id's of a specified
* EntityType
*
* @param keys Collection of EntityKey of various types
* @return List of id's (PK's) from the given key collection that match the concrete EntityType */
default List<Long> extractListOfPKs(final Collection<EntityKey> keys) { default List<Long> extractListOfPKs(final Collection<EntityKey> keys) {
return new ArrayList<>(extractPKsFromKeys(keys)); return new ArrayList<>(extractPKsFromKeys(keys));
} }

View file

@ -12,6 +12,7 @@ import org.joda.time.DateTime;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap; import org.springframework.util.MultiValueMap;
import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.POSTMapper; import ch.ethz.seb.sebserver.gbl.api.POSTMapper;
import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gbl.model.Entity;
import ch.ethz.seb.sebserver.gbl.model.exam.Exam; import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
@ -177,7 +178,7 @@ public class FilterMap extends POSTMapper {
} }
public static String toSQLWildcard(final String text) { public static String toSQLWildcard(final String text) {
return (text == null) ? null : "%" + text + "%"; return (text == null) ? null : Constants.PERCENTAGE + text + Constants.PERCENTAGE;
} }
} }

View file

@ -16,6 +16,10 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
public interface OrientationDAO extends EntityDAO<Orientation, Orientation> { public interface OrientationDAO extends EntityDAO<Orientation, Orientation> {
/** Use this to delete all Orientation of a defined template.
*
* @param templateId the template identifier (PK)
* @return Collection of all EntityKey of Orientations that has been deleted */
Result<Collection<EntityKey>> deleteAllOfTemplate(Long templateId); Result<Collection<EntityKey>> deleteAllOfTemplate(Long templateId);
} }

View file

@ -48,7 +48,7 @@ public interface LmsAPIService {
/** This can be used to test an LmsSetup connection parameter without saving or heaving /** This can be used to test an LmsSetup connection parameter without saving or heaving
* an already persistent version of an LmsSetup. * an already persistent version of an LmsSetup.
* *
* @param lmsSetup * @param lmsSetup
* @return */ * @return */
LmsSetupTestResult testAdHoc(LmsSetup lmsSetup); LmsSetupTestResult testAdHoc(LmsSetup lmsSetup);
@ -76,7 +76,6 @@ public interface LmsAPIService {
return q -> { return q -> {
final boolean nameFilter = StringUtils.isBlank(name) || (q.name != null && q.name.contains(name)); final boolean nameFilter = StringUtils.isBlank(name) || (q.name != null && q.name.contains(name));
final boolean startTimeFilter = (from == null) || (q.startTime != null && q.startTime.isAfter(from)); final boolean startTimeFilter = (from == null) || (q.startTime != null && q.startTime.isAfter(from));
// final boolean endTimeFilter = (now == null) || (q.endTime != null && q.endTime.isAfter(now));
return nameFilter && startTimeFilter /* && endTimeFilter */; return nameFilter && startTimeFilter /* && endTimeFilter */;
}; };
} }

View file

@ -12,16 +12,32 @@ import ch.ethz.seb.sebserver.gbl.api.APIMessage.FieldValidationException;
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationAttribute;
import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue; import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationValue;
/** Defines a validator for validating ConfigurationValue model instances */
public interface ConfigurationValueValidator { public interface ConfigurationValueValidator {
public static final String MESSAGE_VALUE_OBJECT_NAME = "examConfigValue"; public static final String MESSAGE_VALUE_OBJECT_NAME = "examConfigValue";
/** The name of the validator.
* Can be used within the validator field of an ConfigurationAttribute (SQL: configuration_attribute table)
* to force a Validator to validate attribute values of a certain ConfigurationAttribute.
*
* @return name of the validator */
String name(); String name();
/** Indicates if a ConfigurationValue is validated by this concrete validator.
*
* @param value ConfigurationValue instance
* @param attribute ConfigurationAttribute instance
* @return */
boolean validate( boolean validate(
ConfigurationValue value, ConfigurationValue value,
ConfigurationAttribute attribute); ConfigurationAttribute attribute);
/** Default convenient method to handle validation exception if validation failed.
*
* @param value ConfigurationValue instance
* @param attribute ConfigurationAttribute instance
* @throws FieldValidationException the FieldValidationException that is created and thrown */
default void throwValidationError( default void throwValidationError(
final ConfigurationValue value, final ConfigurationValue value,
final ConfigurationAttribute attribute) throws FieldValidationException { final ConfigurationAttribute attribute) throws FieldValidationException {
@ -31,6 +47,11 @@ public interface ConfigurationValueValidator {
this.createErrorMessage(value, attribute)); this.createErrorMessage(value, attribute));
} }
/** Default convenient method to to create an error message in case of validation failure.
*
* @param value ConfigurationValue instance
* @param attribute ConfigurationAttribute instance
* @return error message */
default String createErrorMessage( default String createErrorMessage(
final ConfigurationValue value, final ConfigurationValue value,
final ConfigurationAttribute attribute) { final ConfigurationAttribute attribute) {

View file

@ -38,16 +38,39 @@ public interface SebClientConfigService {
" </dict>\r\n" + " </dict>\r\n" +
" </dict>\r\n"; " </dict>\r\n";
/** Get the server URL prefix in form of;
* [scheme{http|https}]://[server-address{DNS-name|IP}]:[port]
*
* E.g.: https://seb.server.ch:8080
*
* @return the server URL prefix */
String getServerURL(); String getServerURL();
/** Indicates if there is any SebClientConfiguration for a specified institution.
*
* @param institutionId the institution identifier
* @return true if there is any SebClientConfiguration for a specified institution. False otherwise */
boolean hasSebClientConfigurationForInstitution(Long institutionId); boolean hasSebClientConfigurationForInstitution(Long institutionId);
/** Use this to auto-generate a SebClientConfiguration for a specified institution.
* clientName and clientSecret are randomly generated.
*
* @param institutionId the institution identifier
* @return the created SebClientConfig */
Result<SebClientConfig> autoCreateSebClientConfigurationForInstitution(Long institutionId); Result<SebClientConfig> autoCreateSebClientConfigurationForInstitution(Long institutionId);
/** Use this to export a specified SebClientConfiguration within a given OutputStream.
*
* @param out OutputStream to write the export to
* @param modelId the model identifier of the SebClientConfiguration to export */
void exportSebClientConfiguration( void exportSebClientConfiguration(
OutputStream out, OutputStream out,
final String modelId); final String modelId);
/** Use this to get a encoded clientSecret for the SebClientConfiguration with specified clientId/clientName.
*
* @param clientId the clientId/clientName
* @return encoded clientSecret for that SebClientConfiguration with clientId or null of not existing */
Result<String> getEncodedClientSecret(String clientId); Result<String> getEncodedClientSecret(String clientId);
} }

View file

@ -41,6 +41,13 @@ public interface SebConfigCryptor {
final InputStream input, final InputStream input,
final SebConfigEncryptionContext context); final SebConfigEncryptionContext context);
/** Decrypt an incoming cipher data stream to an outgoing plain text data stream
*
* IMPORTANT: This must run in a separated thread
*
* @param output the output stream to write the plain text data to
* @param input the input stream to read the cipher text from
* @param context the SebConfigEncryptionContext to access strategy specific data needed for encryption */
@Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME) @Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME)
void decrypt( void decrypt(
final OutputStream output, final OutputStream output,

View file

@ -52,11 +52,21 @@ public interface SebConfigEncryptionService {
} }
/** This can be used to stream incoming plain text data to encrypted cipher data output stream.
*
* @param output the output data stream to write the cipher text to
* @param input the input stream to read the plain text from
* @param context the SebConfigEncryptionContext to access strategy specific data needed for encryption */
void streamEncrypted( void streamEncrypted(
final OutputStream output, final OutputStream output,
final InputStream input, final InputStream input,
SebConfigEncryptionContext context); SebConfigEncryptionContext context);
/** This can be used to stream incoming cipher data to decrypted plain text data output stream.
*
* @param output the output data stream to write encrypted plain text to
* @param input the input stream to read the cipher text from
* @param context the SebConfigEncryptionContext to access strategy specific data needed for encryption */
void streamDecrypted( void streamDecrypted(
final OutputStream output, final OutputStream output,
final InputStream input, final InputStream input,

View file

@ -163,6 +163,7 @@ sebserver.lmssetup.type.MOODLE=Moodle
sebserver.lmssetup.type.OPEN_EDX=Open edX sebserver.lmssetup.type.OPEN_EDX=Open edX
sebserver.lmssetup.list.actions=Selected LMS Setup sebserver.lmssetup.list.actions=Selected LMS Setup
sebserver.lmssetup.list.action.no.modify.privilege=No Access: A LMS Setup from other institution cannot be modified.
sebserver.lmssetup.list.empty=No LMS Setup has been found. Please adapt the filter or create a new LMS Setup sebserver.lmssetup.list.empty=No LMS Setup has been found. Please adapt the filter or create a new LMS Setup
sebserver.lmssetup.list.title=Learning Management System Setups sebserver.lmssetup.list.title=Learning Management System Setups
sebserver.lmssetup.list.column.institution=Institution sebserver.lmssetup.list.column.institution=Institution
@ -170,6 +171,7 @@ sebserver.lmssetup.list.column.name=Name
sebserver.lmssetup.list.column.type=LMS Type sebserver.lmssetup.list.column.type=LMS Type
sebserver.lmssetup.list.column.active=Active sebserver.lmssetup.list.column.active=Active
sebserver.lmssetup.action.list=LMS Setup sebserver.lmssetup.action.list=LMS Setup
sebserver.lmssetup.action.form=LMS Setup sebserver.lmssetup.action.form=LMS Setup
sebserver.lmssetup.action.new=New LMS Setup sebserver.lmssetup.action.new=New LMS Setup
@ -243,6 +245,7 @@ sebserver.exam.list.column.type=Type
sebserver.exam.list.empty=No Exams has been found. Please adapt the filter or import one from Quiz sebserver.exam.list.empty=No Exams has been found. Please adapt the filter or import one from Quiz
sebserver.exam.list.modify.out.dated=Running or finished exams cannot be modified. sebserver.exam.list.modify.out.dated=Running or finished exams cannot be modified.
sebserver.exam.list.action.no.modify.privilege=No Access: An Exam from other institution cannot be modified.
sebserver.exam.action.list=Exam sebserver.exam.action.list=Exam
sebserver.exam.action.list.view=View Exam sebserver.exam.action.list.view=View Exam
@ -348,6 +351,7 @@ sebserver.clientconfig.list.column.name=Name
sebserver.clientconfig.list.column.date=Creation Date sebserver.clientconfig.list.column.date=Creation Date
sebserver.clientconfig.list.column.active=Active sebserver.clientconfig.list.column.active=Active
sebserver.clientconfig.info.pleaseSelect=Please Select a client configuration first sebserver.clientconfig.info.pleaseSelect=Please Select a client configuration first
sebserver.clientconfig.list.action.no.modify.privilege=No Access: A SEB Client Configuration from other institution cannot be modified.
sebserver.clientconfig.form.title.new=New Client Configuration sebserver.clientconfig.form.title.new=New Client Configuration
sebserver.clientconfig.form.title=SEB Client Configuration sebserver.clientconfig.form.title=SEB Client Configuration
@ -379,6 +383,7 @@ sebserver.examconfig.list.actions=Selected Configuration
sebserver.examconfig.list.empty=There is currently no SEB-Exam configuration available. Please create a new one sebserver.examconfig.list.empty=There is currently no SEB-Exam configuration available. Please create a new one
sebserver.examconfig.info.pleaseSelect=Please Select an exam configuration first sebserver.examconfig.info.pleaseSelect=Please Select an exam configuration first
sebserver.examconfig.list.action.no.modify.privilege=No Access: An Exam Configuration from other institution cannot be modified.
sebserver.examconfig.action.list.new=New Exam Configuration sebserver.examconfig.action.list.new=New Exam Configuration
sebserver.examconfig.action.list.view=View Configuration sebserver.examconfig.action.list.view=View Configuration