fixes code cleanup and docu
This commit is contained in:
parent
f53243e001
commit
4e4883b8b7
19 changed files with 169 additions and 34 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)));
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue