SEBSERV-473 fixed list and sorting
This commit is contained in:
		
							parent
							
								
									73c0c8627c
								
							
						
					
					
						commit
						6be552b8d3
					
				
					 14 changed files with 73 additions and 68 deletions
				
			
		|  | @ -173,10 +173,10 @@ public class UserActivityLogs implements TemplateComposer { | ||||||
|                             } |                             } | ||||||
|                         }); |                         }); | ||||||
| 
 | 
 | ||||||
|         final Consumer<Boolean> deleteActionActivation = this.pageService.getActionActiviationPublisher( |         final Consumer<Boolean> deleteActionActivation = this.pageService.getActionActivationPublisher( | ||||||
|                 pageContext, |                 pageContext, | ||||||
|                 ActionDefinition.LOGS_USER_ACTIVITY_DELETE_ALL); |                 ActionDefinition.LOGS_USER_ACTIVITY_DELETE_ALL); | ||||||
|         final Consumer<Boolean> detailsActionActivation = this.pageService.getActionActiviationPublisher( |         final Consumer<Boolean> detailsActionActivation = this.pageService.getActionActivationPublisher( | ||||||
|                 pageContext, |                 pageContext, | ||||||
|                 ActionDefinition.LOGS_USER_ACTIVITY_SHOW_DETAILS); |                 ActionDefinition.LOGS_USER_ACTIVITY_SHOW_DETAILS); | ||||||
|         final Consumer<Integer> contentChangeListener = contentSize -> { |         final Consumer<Integer> contentChangeListener = contentSize -> { | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ import java.util.function.Predicate; | ||||||
| import java.util.function.Supplier; | import java.util.function.Supplier; | ||||||
| import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||||
| 
 | 
 | ||||||
|  | import org.apache.commons.lang3.ObjectUtils; | ||||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||||
| import org.eclipse.swt.widgets.Composite; | import org.eclipse.swt.widgets.Composite; | ||||||
| import org.springframework.context.annotation.Lazy; | import org.springframework.context.annotation.Lazy; | ||||||
|  | @ -173,6 +174,7 @@ public class AddSecurityKeyGrantPopup { | ||||||
|                                 .getBuilder(GetClientConnections.class) |                                 .getBuilder(GetClientConnections.class) | ||||||
|                                 .withQueryParam(API.PARAM_MODEL_ID_LIST, clientConnectionIds) |                                 .withQueryParam(API.PARAM_MODEL_ID_LIST, clientConnectionIds) | ||||||
|                                 .call().getOrThrow()); |                                 .call().getOrThrow()); | ||||||
|  |                         list.sort((cc1, cc2) -> ObjectUtils.compare(cc1.userSessionId, cc2.userSessionId)); | ||||||
|                         this.pageService.staticListTableBuilder(list, EntityType.CLIENT_CONNECTION) |                         this.pageService.staticListTableBuilder(list, EntityType.CLIENT_CONNECTION) | ||||||
|                                 .withPaging(10) |                                 .withPaging(10) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -63,7 +63,7 @@ public class SecurityKeyGrantPopup { | ||||||
|         return action; |         return action; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private final class PopupComposer { |     private static final class PopupComposer { | ||||||
| 
 | 
 | ||||||
|         private final PageService pageService; |         private final PageService pageService; | ||||||
|         private final SecurityKey securityKey; |         private final SecurityKey securityKey; | ||||||
|  |  | ||||||
|  | @ -150,10 +150,10 @@ public class SEBClientEvents implements TemplateComposer { | ||||||
|         final boolean writeGrant = this.pageService.getCurrentUser() |         final boolean writeGrant = this.pageService.getCurrentUser() | ||||||
|                 .hasInstitutionalPrivilege(PrivilegeType.WRITE, EntityType.CLIENT_EVENT); |                 .hasInstitutionalPrivilege(PrivilegeType.WRITE, EntityType.CLIENT_EVENT); | ||||||
| 
 | 
 | ||||||
|         final Consumer<Boolean> deleteActionActivation = this.pageService.getActionActiviationPublisher( |         final Consumer<Boolean> deleteActionActivation = this.pageService.getActionActivationPublisher( | ||||||
|                 pageContext, |                 pageContext, | ||||||
|                 ActionDefinition.LOGS_SEB_CLIENT_DELETE_ALL); |                 ActionDefinition.LOGS_SEB_CLIENT_DELETE_ALL); | ||||||
|         final Consumer<Boolean> detailsActionActivation = this.pageService.getActionActiviationPublisher( |         final Consumer<Boolean> detailsActionActivation = this.pageService.getActionActivationPublisher( | ||||||
|                 pageContext, |                 pageContext, | ||||||
|                 ActionDefinition.LOGS_SEB_CLIENT_SHOW_DETAILS); |                 ActionDefinition.LOGS_SEB_CLIENT_SHOW_DETAILS); | ||||||
|         final Consumer<Integer> contentChangeListener = contentSize -> { |         final Consumer<Integer> contentChangeListener = contentSize -> { | ||||||
|  |  | ||||||
|  | @ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.gui.service.page; | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
|  | import java.util.UUID; | ||||||
| import java.util.function.BooleanSupplier; | import java.util.function.BooleanSupplier; | ||||||
| import java.util.function.Consumer; | import java.util.function.Consumer; | ||||||
| import java.util.function.Function; | import java.util.function.Function; | ||||||
|  | @ -138,7 +139,7 @@ public interface PageService { | ||||||
|      * @param noSelectionText LocTextKey for missing selection message |      * @param noSelectionText LocTextKey for missing selection message | ||||||
|      * @param testBeforeActivation a function to test before activation. This function shall throw an error if test |      * @param testBeforeActivation a function to test before activation. This function shall throw an error if test | ||||||
|      *            fails. |      *            fails. | ||||||
|      *            My be null if no specific test is needed before activation |      *            May be null if no specific test is needed before activation | ||||||
|      * @return page action execution function for switching the activity */ |      * @return page action execution function for switching the activity */ | ||||||
|     <T extends Entity & Activatable> Function<PageAction, PageAction> activationToggleActionFunction( |     <T extends Entity & Activatable> Function<PageAction, PageAction> activationToggleActionFunction( | ||||||
|             EntityTable<T> table, |             EntityTable<T> table, | ||||||
|  | @ -161,7 +162,7 @@ public interface PageService { | ||||||
|      * |      * | ||||||
|      * @param entity the entity instance |      * @param entity the entity instance | ||||||
|      * @return a message supplier to notify deactivation dependencies to the user */ |      * @return a message supplier to notify deactivation dependencies to the user */ | ||||||
|     <T extends Entity & Activatable> Supplier<LocTextKey> confirmDeactivation(final T entity); |     <T extends Entity & Activatable> Supplier<LocTextKey> confirmDeactivation(T entity); | ||||||
| 
 | 
 | ||||||
|     /** Get a message supplier to notify deactivation dependencies to the user for given entity table selection |     /** Get a message supplier to notify deactivation dependencies to the user for given entity table selection | ||||||
|      * |      * | ||||||
|  | @ -188,17 +189,17 @@ public interface PageService { | ||||||
|      * |      * | ||||||
|      * @param pageContext the current PageContext |      * @param pageContext the current PageContext | ||||||
|      * @param actionDefinitions list of action definitions that activity should be toggled on table selection |      * @param actionDefinitions list of action definitions that activity should be toggled on table selection | ||||||
|      * @return the action activation publisher that can be used to control the activity of an certain action */ |      * @return the action activation publisher that can be used to control the activity of a certain action */ | ||||||
|     default Consumer<Boolean> getActionActiviationPublisher( |     default Consumer<Boolean> getActionActivationPublisher( | ||||||
|             final PageContext pageContext, |             final PageContext pageContext, | ||||||
|             final ActionDefinition... actionDefinitions) { |             final ActionDefinition... actionDefinitions) { | ||||||
| 
 | 
 | ||||||
|         return avtivate -> firePageEvent( |         return activate -> firePageEvent( | ||||||
|                 new ActionActivationEvent(avtivate, actionDefinitions), |                 new ActionActivationEvent(activate, actionDefinitions), | ||||||
|                 pageContext); |                 pageContext); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** Use this to get an table selection action publisher that processes the action |     /** Use this to get a table selection action publisher that processes the action | ||||||
|      * activation on table selection. |      * activation on table selection. | ||||||
|      * |      * | ||||||
|      * @param pageContext the current PageContext |      * @param pageContext the current PageContext | ||||||
|  | @ -213,10 +214,10 @@ public interface PageService { | ||||||
|                 pageContext); |                 pageContext); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** Use this to get an table selection action publisher that processes the action |     /** Use this to get a table selection action publisher that processes the action | ||||||
|      * activation on table selection. |      * activation on table selection. | ||||||
|      * </p> |      * </p> | ||||||
|      * This additional has the ability to define a entity activity action that is toggles in |      * This additional has the ability to define an entity activity action that is toggles in | ||||||
|      * case of the selected entity |      * case of the selected entity | ||||||
|      * |      * | ||||||
|      * @param toggle the base entity activity action definition |      * @param toggle the base entity activity action definition | ||||||
|  | @ -254,7 +255,7 @@ public interface PageService { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** Publishes a given PageEvent to the current page tree |     /** Publishes a given PageEvent to the current page tree | ||||||
|      * This goes through the page-tree and collects all listeners the are listen to |      * This goes through the page-tree and collects all listeners they are listen to | ||||||
|      * the specified page event type. |      * the specified page event type. | ||||||
|      * |      * | ||||||
|      * @param event the concrete PageEvent instance */ |      * @param event the concrete PageEvent instance */ | ||||||
|  | @ -277,23 +278,23 @@ public interface PageService { | ||||||
| 
 | 
 | ||||||
|     /** Publishes a PageAction to the current page. This uses the firePageEvent form |     /** Publishes a PageAction to the current page. This uses the firePageEvent form | ||||||
|      * PageContext of the given PageAction and fires a ActionPublishEvent for the given PageAction |      * PageContext of the given PageAction and fires a ActionPublishEvent for the given PageAction | ||||||
|      * |      * <p> | ||||||
|      * All ActionPublishEventListeners that are registered within the current page will |      * All ActionPublishEventListeners that are registered within the current page will | ||||||
|      * receive the ActionPublishEvent sent by this. |      * receive the ActionPublishEvent sent by this. | ||||||
|      * |      * | ||||||
|      * @param pageAction the PageAction to publish |      * @param pageAction the PageAction to publish | ||||||
|      * @param active indicates whether the action is active or not */ |      * @param active indicates whether the action is active or not */ | ||||||
|     void publishAction(final PageAction pageAction, boolean active); |     void publishAction(PageAction pageAction, boolean active); | ||||||
| 
 | 
 | ||||||
|     /** Publishes a PageAction to the current page. This uses the firePageEvent form |     /** Publishes a PageAction to the current page. This uses the firePageEvent form | ||||||
|      * PageContext of the given PageAction and fires a ActionPublishEvent for the given PageAction |      * PageContext of the given PageAction and fires a ActionPublishEvent for the given PageAction | ||||||
|      * |      * <p> | ||||||
|      * All ActionPublishEventListeners that are registered within the current page will |      * All ActionPublishEventListeners that are registered within the current page will | ||||||
|      * receive the ActionPublishEvent sent by this. |      * receive the ActionPublishEvent sent by this. | ||||||
|      * |      * | ||||||
|      * @param pageAction the PageAction to publish |      * @param pageAction the PageAction to publish | ||||||
|      * @param actionConsumer An consumer that gets the actions TreeItem after creation */ |      * @param actionConsumer A consumer that gets the actions TreeItem after creation */ | ||||||
|     void publishAction(final PageAction pageAction, Consumer<TreeItem> actionConsumer); |     void publishAction(PageAction pageAction, Consumer<TreeItem> actionConsumer); | ||||||
| 
 | 
 | ||||||
|     /** Get a new FormBuilder for the given PageContext |     /** Get a new FormBuilder for the given PageContext | ||||||
|      * This FormBuilder uses the standard form grid which has 8 rows (2 title, 5 input and 1 right-space) |      * This FormBuilder uses the standard form grid which has 8 rows (2 title, 5 input and 1 right-space) | ||||||
|  | @ -307,11 +308,11 @@ public interface PageService { | ||||||
|     /** Get a new FormBuilder for the given PageContext and with number of rows. |     /** Get a new FormBuilder for the given PageContext and with number of rows. | ||||||
|      * |      * | ||||||
|      * @param pageContext the PageContext on that the FormBuilder should work |      * @param pageContext the PageContext on that the FormBuilder should work | ||||||
|      * @param rows the number of rows of the from |      * @param rows the number of rows of the form | ||||||
|      * @return a FormBuilder instance for the given PageContext and with number of rows */ |      * @return a FormBuilder instance for the given PageContext and with number of rows */ | ||||||
|     FormBuilder formBuilder(PageContext pageContext, int rows); |     FormBuilder formBuilder(PageContext pageContext, int rows); | ||||||
| 
 | 
 | ||||||
|     /** Get an new TableBuilder for specified page based RestCall. |     /** Get a new TableBuilder for specified page based RestCall. | ||||||
|      * |      * | ||||||
|      * @param apiCall the SEB Server API RestCall that feeds the table with data |      * @param apiCall the SEB Server API RestCall that feeds the table with data | ||||||
|      * @param <T> the type of the Entity of the table |      * @param <T> the type of the Entity of the table | ||||||
|  | @ -320,7 +321,7 @@ public interface PageService { | ||||||
|         return entityTableBuilder(this.getRestService().getRestCall(apiCall)); |         return entityTableBuilder(this.getRestService().getRestCall(apiCall)); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** Get an new TableBuilder for specified page based RestCall. |     /** Get a new TableBuilder for specified page based RestCall. | ||||||
|      * |      * | ||||||
|      * @param apiCall the SEB Server API RestCall that feeds the table with data |      * @param apiCall the SEB Server API RestCall that feeds the table with data | ||||||
|      * @param <T> the type of the Entity of the table |      * @param <T> the type of the Entity of the table | ||||||
|  | @ -329,7 +330,7 @@ public interface PageService { | ||||||
|         return entityTableBuilder(apiCall.getClass().getSimpleName(), apiCall); |         return entityTableBuilder(apiCall.getClass().getSimpleName(), apiCall); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** Get an new TableBuilder for specified page based RestCall. |     /** Get a new TableBuilder for specified page based RestCall. | ||||||
|      * |      * | ||||||
|      * @param name The name of the table to build |      * @param name The name of the table to build | ||||||
|      * @param apiCall the SEB Server API RestCall that feeds the table with data |      * @param apiCall the SEB Server API RestCall that feeds the table with data | ||||||
|  | @ -339,7 +340,15 @@ public interface PageService { | ||||||
|             String name, |             String name, | ||||||
|             RestCall<Page<T>> apiCall); |             RestCall<Page<T>> apiCall); | ||||||
| 
 | 
 | ||||||
|     <T extends ModelIdAware> TableBuilder<T> staticListTableBuilder(final List<T> staticList, EntityType entityType); |     default <T extends ModelIdAware> TableBuilder<T> staticListTableBuilder( | ||||||
|  |             final List<T> staticList, | ||||||
|  |             final EntityType entityType) { | ||||||
|  |         return staticListTableBuilder(UUID.randomUUID().toString(), staticList, entityType); | ||||||
|  |     } | ||||||
|  |     <T extends ModelIdAware> TableBuilder<T> staticListTableBuilder( | ||||||
|  |             String name, | ||||||
|  |             List<T> staticList, | ||||||
|  |             EntityType entityType); | ||||||
| 
 | 
 | ||||||
|     <T extends ModelIdAware> TableBuilder<T> remoteListTableBuilder( |     <T extends ModelIdAware> TableBuilder<T> remoteListTableBuilder( | ||||||
|             RestCall<Collection<T>> apiCall, |             RestCall<Collection<T>> apiCall, | ||||||
|  | @ -353,7 +362,7 @@ public interface PageService { | ||||||
|         return new PageActionBuilder(this, pageContext); |         return new PageActionBuilder(this, pageContext); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** This triggers a logout on the current authorization context to logout the current user |     /** This triggers a logout on the current authorization context to log out the current user | ||||||
|      * and forward to the login page with showing a successful logout message to the user. */ |      * and forward to the login page with showing a successful logout message to the user. */ | ||||||
|     boolean logout(PageContext pageContext); |     boolean logout(PageContext pageContext); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -370,14 +370,11 @@ public class PageServiceImpl implements PageService { | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public <T extends ModelIdAware> TableBuilder<T> staticListTableBuilder( |     public <T extends ModelIdAware> TableBuilder<T> staticListTableBuilder( | ||||||
|  |             final String name, | ||||||
|             final List<T> staticList, |             final List<T> staticList, | ||||||
|             final EntityType entityType) { |             final EntityType entityType) { | ||||||
| 
 | 
 | ||||||
|         return new TableBuilder<>( |         return new TableBuilder<>(name,this, staticList, entityType); | ||||||
|                 (entityType != null) |  | ||||||
|                         ? entityType.name() |  | ||||||
|                         : "", |  | ||||||
|                 this, staticList, entityType); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|  |  | ||||||
|  | @ -117,6 +117,11 @@ public class StaticListPageSupplier<T> implements PageSupplier<T> { | ||||||
|                 if (to >= this.list.size()) { |                 if (to >= this.list.size()) { | ||||||
|                     to = this.list.size(); |                     to = this.list.size(); | ||||||
|                 } |                 } | ||||||
|  |                 if (from >= to) { | ||||||
|  |                     from = 0; | ||||||
|  |                     to = Math.min(this.pageSize, this.list.size()); | ||||||
|  |                     this.pageNumber = 1; | ||||||
|  |                 } | ||||||
| 
 | 
 | ||||||
|                 final List<T> subList = this.list.subList(from, to); |                 final List<T> subList = this.list.subList(from, to); | ||||||
|                 return new Page<>(numOfPages, this.pageNumber, this.pageSize, this.column, subList); |                 return new Page<>(numOfPages, this.pageNumber, this.pageSize, this.column, subList); | ||||||
|  |  | ||||||
|  | @ -35,7 +35,7 @@ public interface ClientConnectionDAO extends | ||||||
| 
 | 
 | ||||||
|     /** Get a list of all connection tokens of all connections (no matter what state) |     /** Get a list of all connection tokens of all connections (no matter what state) | ||||||
|      * of an exam. |      * of an exam. | ||||||
|      * |      * <p> | ||||||
|      * Caches the resulting collection of tokens with the given examId as key |      * Caches the resulting collection of tokens with the given examId as key | ||||||
|      * unless the result has no error. |      * unless the result has no error. | ||||||
|      * |      * | ||||||
|  | @ -77,7 +77,7 @@ public interface ClientConnectionDAO extends | ||||||
|      * |      * | ||||||
|      * @param connectionTokens The set of connection tokens to filter |      * @param connectionTokens The set of connection tokens to filter | ||||||
|      * @return Result refer to all inactive connection tokens from the given set */ |      * @return Result refer to all inactive connection tokens from the given set */ | ||||||
|     Result<Collection<String>> getInactiveConnctionTokens(Set<String> connectionTokens); |     Result<Collection<String>> getInactiveConnectionTokens(Set<String> connectionTokens); | ||||||
| 
 | 
 | ||||||
|     /** Get a collection of all client connections records that needs a proctoring room update |     /** Get a collection of all client connections records that needs a proctoring room update | ||||||
|      * and that are in the status ACTIVE. |      * and that are in the status ACTIVE. | ||||||
|  | @ -151,7 +151,7 @@ public interface ClientConnectionDAO extends | ||||||
|     @CacheEvict( |     @CacheEvict( | ||||||
|             cacheNames = ExamSessionCacheService.CACHE_NAME_ACTIVE_CLIENT_CONNECTION, |             cacheNames = ExamSessionCacheService.CACHE_NAME_ACTIVE_CLIENT_CONNECTION, | ||||||
|             key = "#connectionToken") |             key = "#connectionToken") | ||||||
|     Result<Void> markScreenProcotringApplied(Long connectionId, String connectionToken); |     Result<Void> markScreenProctoringApplied(Long connectionId, String connectionToken); | ||||||
| 
 | 
 | ||||||
|     /** Get a ClientConnection by connection token. |     /** Get a ClientConnection by connection token. | ||||||
|      * |      * | ||||||
|  | @ -159,10 +159,10 @@ public interface ClientConnectionDAO extends | ||||||
|      * @return Result refer to the ClientConnection for the specified connection token or to an error if happened */ |      * @return Result refer to the ClientConnection for the specified connection token or to an error if happened */ | ||||||
|     Result<ClientConnection> byConnectionToken(String connectionToken); |     Result<ClientConnection> byConnectionToken(String connectionToken); | ||||||
| 
 | 
 | ||||||
|     /** Use this to check whether a single ClientConnection is up to date or needs a refresh. |     /** Use this to check whether a single ClientConnection is up-to-date or needs a refresh. | ||||||
|      * |      * | ||||||
|      * @param clientConnection the actual ClientConnection (from the internal cache) |      * @param clientConnection the actual ClientConnection (from the internal cache) | ||||||
|      * @return Result refer to true if the given ClientConnection is up to date */ |      * @return Result refer to true if the given ClientConnection is up-to-date */ | ||||||
|     Result<Boolean> isUpToDate(ClientConnection clientConnection); |     Result<Boolean> isUpToDate(ClientConnection clientConnection); | ||||||
| 
 | 
 | ||||||
|     Result<Set<String>> getClientConnectionsOutOfSyc(Long examId, Set<Long> timestamps); |     Result<Set<String>> getClientConnectionsOutOfSyc(Long examId, Set<Long> timestamps); | ||||||
|  | @ -183,7 +183,7 @@ public interface ClientConnectionDAO extends | ||||||
|      * @return Result refer to filtered Set of connection tokens or to an error when happened */ |      * @return Result refer to filtered Set of connection tokens or to an error when happened */ | ||||||
|     Result<Set<String>> filterForInstructionStatus(Long examId, Set<String> connectionToken); |     Result<Set<String>> filterForInstructionStatus(Long examId, Set<String> connectionToken); | ||||||
| 
 | 
 | ||||||
|     /** Used to get the VDI paired connection if it already exsits. |     /** Used to get the VDI paired connection if it already exists. | ||||||
|      * |      * | ||||||
|      * @param clientName the VDI connection identifier sent by the SEB client on connect |      * @param clientName the VDI connection identifier sent by the SEB client on connect | ||||||
|      * @return Result refer to the relevant VDI pair connection if exists or to an error if not */ |      * @return Result refer to the relevant VDI pair connection if exists or to an error if not */ | ||||||
|  | @ -200,27 +200,27 @@ public interface ClientConnectionDAO extends | ||||||
|      * |      * | ||||||
|      * @param examId the exam identifier |      * @param examId the exam identifier | ||||||
|      * @return Result refer to a collection of client connection records or to an error when happened */ |      * @return Result refer to a collection of client connection records or to an error when happened */ | ||||||
|     Result<Collection<ClientConnectionRecord>> getsecurityKeyConnectionRecords(Long examId); |     Result<Collection<ClientConnectionRecord>> getSecurityKeyConnectionRecords(Long examId); | ||||||
| 
 | 
 | ||||||
|     /** Get all client connection records that don't have a security access grant yet |     /** Get all client connection records that don't have a security access grant yet | ||||||
|      * and for specific exam. |      * and for specific exam. | ||||||
|      * |      * | ||||||
|      * @param examId The exam identifier |      * @param examId The exam identifier | ||||||
|      * @return Result refer to client connection records to the an error when happened */ |      * @return Result refer to client connection records to an error when happened */ | ||||||
|     Result<Collection<ClientConnectionRecord>> getAllActiveNotGranted(Long examId); |     Result<Collection<ClientConnectionRecord>> getAllActiveNotGranted(Long examId); | ||||||
| 
 | 
 | ||||||
|     /** Count all known and matching ASK hashes for a given exam. |     /** Count all known and matching ASK hashes for a given exam. | ||||||
|      * |      * | ||||||
|      * @param examId The exam identifier |      * @param examId The exam identifier | ||||||
|      * @param signatureHash The signature hash the count |      * @param signatureHash The signature hash the count | ||||||
|      * @return Result refer to the signature hash count or to an result when happened */ |      * @return Result refer to the signature hash count or to result when happened */ | ||||||
|     Result<Long> countSignatureHashes(Long examId, String signatureHash); |     Result<Long> countSignatureHashes(Long examId, String signatureHash); | ||||||
| 
 | 
 | ||||||
|     /** Get all client connection records that don't have a SEB client version check yet |     /** Get all client connection records that don't have a SEB client version check yet | ||||||
|      * and for specific exam. |      * and for specific exam. | ||||||
|      * |      * | ||||||
|      * @param examId The exam identifier |      * @param examId The exam identifier | ||||||
|      * @return Result refer to client connection records to the an error when happened */ |      * @return Result refer to client connection records to the error when happened */ | ||||||
|     Result<Collection<ClientConnectionRecord>> getAllActiveNoSEBVersionCheck(Long examId); |     Result<Collection<ClientConnectionRecord>> getAllActiveNoSEBVersionCheck(Long examId); | ||||||
| 
 | 
 | ||||||
|     /** Get all client connection identifiers for an exam. |     /** Get all client connection identifiers for an exam. | ||||||
|  |  | ||||||
|  | @ -273,7 +273,7 @@ public class ClientConnectionDAOImpl implements ClientConnectionDAO { | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     @Transactional(readOnly = true) |     @Transactional(readOnly = true) | ||||||
|     public Result<Collection<String>> getInactiveConnctionTokens(final Set<String> connectionTokens) { |     public Result<Collection<String>> getInactiveConnectionTokens(final Set<String> connectionTokens) { | ||||||
|         return Result.tryCatch(() -> { |         return Result.tryCatch(() -> { | ||||||
|             if (connectionTokens == null || connectionTokens.isEmpty()) { |             if (connectionTokens == null || connectionTokens.isEmpty()) { | ||||||
|                 return Collections.emptyList(); |                 return Collections.emptyList(); | ||||||
|  | @ -597,7 +597,7 @@ public class ClientConnectionDAOImpl implements ClientConnectionDAO { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     public Result<Void> markScreenProcotringApplied(final Long connectionId, final String connectionToken) { |     public Result<Void> markScreenProctoringApplied(final Long connectionId, final String connectionToken) { | ||||||
|         return Result.tryCatch(() -> { |         return Result.tryCatch(() -> { | ||||||
|             UpdateDSL.updateWithMapper( |             UpdateDSL.updateWithMapper( | ||||||
|                     this.clientConnectionRecordMapper::update, |                     this.clientConnectionRecordMapper::update, | ||||||
|  | @ -843,15 +843,15 @@ public class ClientConnectionDAOImpl implements ClientConnectionDAO { | ||||||
| 
 | 
 | ||||||
|     @Override |     @Override | ||||||
|     @Transactional(readOnly = true) |     @Transactional(readOnly = true) | ||||||
|     public Result<Collection<ClientConnectionRecord>> getsecurityKeyConnectionRecords(final Long examId) { |     public Result<Collection<ClientConnectionRecord>> getSecurityKeyConnectionRecords(final Long examId) { | ||||||
|         return Result.tryCatch(() -> this.clientConnectionRecordMapper |         return Result.tryCatch(() -> this.clientConnectionRecordMapper | ||||||
|                 .selectByExample() |                 .selectByExample() | ||||||
|                 .where( |                 .where( | ||||||
|                         ClientConnectionRecordDynamicSqlSupport.examId, |                         ClientConnectionRecordDynamicSqlSupport.examId, | ||||||
|                         SqlBuilder.isEqualTo(examId)) |                         SqlBuilder.isEqualTo(examId)) | ||||||
|                 .and( | //                .and( | ||||||
|                         ClientConnectionRecordDynamicSqlSupport.status, | //                        ClientConnectionRecordDynamicSqlSupport.status, | ||||||
|                         SqlBuilder.isIn(ClientConnection.SECURE_STATES)) | //                        SqlBuilder.isIn(ClientConnection.SECURE_STATES)) | ||||||
|                 .build() |                 .build() | ||||||
|                 .execute()); |                 .execute()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -60,7 +60,7 @@ public interface SecurityKeyService { | ||||||
|      * @return Result refer to the newly created security key entry or to an error when happened */ |      * @return Result refer to the newly created security key entry or to an error when happened */ | ||||||
|     Result<SecurityKey> grantAppSignatureKey(Long institutionId, Long examId, Long connectionId, String tag); |     Result<SecurityKey> grantAppSignatureKey(Long institutionId, Long examId, Long connectionId, String tag); | ||||||
| 
 | 
 | ||||||
|     /** Get the hashed App Signature Key value from a encrypted App Signature Key sent by a SEB client. |     /** Get the hashed App Signature Key value from an encrypted App Signature Key sent by a SEB client. | ||||||
|      * The App Signature Key hash is used for security checks. The plain App Signature Key will never be used nor stored |      * The App Signature Key hash is used for security checks. The plain App Signature Key will never be used nor stored | ||||||
|      * |      * | ||||||
|      * @param appSignatureKey The encrypted App Signature Key sent by a SEB client |      * @param appSignatureKey The encrypted App Signature Key sent by a SEB client | ||||||
|  | @ -72,8 +72,8 @@ public interface SecurityKeyService { | ||||||
|             CharSequence salt); |             CharSequence salt); | ||||||
| 
 | 
 | ||||||
|     /** Use this to update an App Signature Key grant for a particular SEB connection. This will |     /** Use this to update an App Signature Key grant for a particular SEB connection. This will | ||||||
|      * apply the security check again and mark the connection regarding to the security check. |      * apply the security check again and mark the connection regarding the security check. | ||||||
|      * |      * <p> | ||||||
|      * This is used by the internal monitoring update task |      * This is used by the internal monitoring update task | ||||||
|      * |      * | ||||||
|      * @param record The ClientConnectionRecord of the specific SEB client connection */ |      * @param record The ClientConnectionRecord of the specific SEB client connection */ | ||||||
|  |  | ||||||
|  | @ -85,7 +85,7 @@ public class SecurityKeyServiceImpl implements SecurityKeyService { | ||||||
|         return Result.tryCatch(() -> { |         return Result.tryCatch(() -> { | ||||||
| 
 | 
 | ||||||
|             return this.clientConnectionDAO |             return this.clientConnectionDAO | ||||||
|                     .getsecurityKeyConnectionRecords(examId) |                     .getSecurityKeyConnectionRecords(examId) | ||||||
|                     .getOrThrow() |                     .getOrThrow() | ||||||
|                     .stream() |                     .stream() | ||||||
|                     .reduce( |                     .reduce( | ||||||
|  | @ -94,6 +94,7 @@ public class SecurityKeyServiceImpl implements SecurityKeyService { | ||||||
|                             Utils::<String, Map<Long, String>> mergeMap) |                             Utils::<String, Map<Long, String>> mergeMap) | ||||||
|                     .entrySet() |                     .entrySet() | ||||||
|                     .stream() |                     .stream() | ||||||
|  |                     .filter(m -> m.getValue() != null && !m.getValue().isEmpty()) | ||||||
|                     .map(m -> new AppSignatureKeyInfo(institutionId, examId, m.getKey(), m.getValue())) |                     .map(m -> new AppSignatureKeyInfo(institutionId, examId, m.getKey(), m.getValue())) | ||||||
|                     .collect(Collectors.toList()); |                     .collect(Collectors.toList()); | ||||||
|         }); |         }); | ||||||
|  | @ -179,7 +180,7 @@ public class SecurityKeyServiceImpl implements SecurityKeyService { | ||||||
| 
 | 
 | ||||||
|         return Cryptor |         return Cryptor | ||||||
|                 .decryptASK(appSignatureKey, connectionToken, salt) |                 .decryptASK(appSignatureKey, connectionToken, salt) | ||||||
|                 .map(signature -> createSignatureHash(signature)); |                 .map(this::createSignatureHash); | ||||||
| 
 | 
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | @ -218,7 +219,7 @@ public class SecurityKeyServiceImpl implements SecurityKeyService { | ||||||
| 
 | 
 | ||||||
|             final String grantedKeyHash = String.valueOf(key); |             final String grantedKeyHash = String.valueOf(key); | ||||||
|             this.securityKeyRegistryDAO.delete(keyId).getOrThrow(); |             this.securityKeyRegistryDAO.delete(keyId).getOrThrow(); | ||||||
|             this.clientConnectionDAO.getsecurityKeyConnectionRecords(key.examId) |             this.clientConnectionDAO.getSecurityKeyConnectionRecords(key.examId) | ||||||
|                     .getOrThrow() |                     .getOrThrow() | ||||||
|                     .stream() |                     .stream() | ||||||
|                     .filter(rec -> ConnectionStatus.ACTIVE.name().equals(rec.getStatus())) |                     .filter(rec -> ConnectionStatus.ACTIVE.name().equals(rec.getStatus())) | ||||||
|  | @ -271,18 +272,14 @@ public class SecurityKeyServiceImpl implements SecurityKeyService { | ||||||
|                             .filter(key -> Utils.isEqualsWithEmptyCheck(String.valueOf(key.key), hashedSignatureKey)) |                             .filter(key -> Utils.isEqualsWithEmptyCheck(String.valueOf(key.key), hashedSignatureKey)) | ||||||
|                             .collect(Collectors.toList()); |                             .collect(Collectors.toList()); | ||||||
| 
 | 
 | ||||||
|                     if (matches == null || matches.isEmpty()) { |                     if (matches.isEmpty()) { | ||||||
|                         return numericalCheck(examId, hashedSignatureKey); |                         return numericalCheck(examId, hashedSignatureKey); | ||||||
|                     } else { |                     } else { | ||||||
|                         return new SecurityCheckResult( |                         return new SecurityCheckResult( | ||||||
|                                 matches.stream() |                                 matches.stream() | ||||||
|                                         .filter(key -> key.examId != null) |                                         .anyMatch(key -> key.examId != null), | ||||||
|                                         .findFirst() |  | ||||||
|                                         .isPresent(), |  | ||||||
|                                 matches.stream() |                                 matches.stream() | ||||||
|                                         .filter(key -> key.examId == null) |                                         .anyMatch(key -> key.examId == null), | ||||||
|                                         .findFirst() |  | ||||||
|                                         .isPresent(), |  | ||||||
|                                 false); |                                 false); | ||||||
|                     } |                     } | ||||||
|                 }); |                 }); | ||||||
|  | @ -350,8 +347,7 @@ public class SecurityKeyServiceImpl implements SecurityKeyService { | ||||||
|         try { |         try { | ||||||
|             final MessageDigest hasher = MessageDigest.getInstance(Constants.SHA_256); |             final MessageDigest hasher = MessageDigest.getInstance(Constants.SHA_256); | ||||||
|             hasher.update(Utils.toByteArray(signature)); |             hasher.update(Utils.toByteArray(signature)); | ||||||
|             final String signatureHash = Hex.toHexString(hasher.digest()); |             return Hex.toHexString(hasher.digest()); | ||||||
|             return signatureHash; |  | ||||||
|         } catch (final Exception e) { |         } catch (final Exception e) { | ||||||
|             throw new RuntimeException(e); |             throw new RuntimeException(e); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -306,7 +306,7 @@ public class SEBClientInstructionServiceImpl implements SEBClientInstructionServ | ||||||
|         synchronized (this.instructions) { |         synchronized (this.instructions) { | ||||||
| 
 | 
 | ||||||
|             final Result<Collection<String>> result = this.clientConnectionDAO |             final Result<Collection<String>> result = this.clientConnectionDAO | ||||||
|                     .getInactiveConnctionTokens(this.instructions.keySet()); |                     .getInactiveConnectionTokens(this.instructions.keySet()); | ||||||
| 
 | 
 | ||||||
|             if (result.hasValue()) { |             if (result.hasValue()) { | ||||||
|                 result.get().stream().forEach(token -> this.instructions.remove(token)); |                 result.get().stream().forEach(token -> this.instructions.remove(token)); | ||||||
|  |  | ||||||
|  | @ -317,7 +317,7 @@ public class ScreenProctoringServiceImpl implements ScreenProctoringService { | ||||||
|             registerJoinInstruction(ccRecord, spsSessionToken, group, runningExam); |             registerJoinInstruction(ccRecord, spsSessionToken, group, runningExam); | ||||||
| 
 | 
 | ||||||
|             this.clientConnectionDAO |             this.clientConnectionDAO | ||||||
|                     .markScreenProcotringApplied(ccRecord.getId(), ccRecord.getConnectionToken()) |                     .markScreenProctoringApplied(ccRecord.getId(), ccRecord.getConnectionToken()) | ||||||
|                     .getOrThrow(); |                     .getOrThrow(); | ||||||
| 
 | 
 | ||||||
|         } catch (final Exception e) { |         } catch (final Exception e) { | ||||||
|  |  | ||||||
|  | @ -9,7 +9,6 @@ | ||||||
| package ch.ethz.seb.sebserver.webservice.weblayer.api; | package ch.ethz.seb.sebserver.webservice.weblayer.api; | ||||||
| 
 | 
 | ||||||
| import java.util.*; | import java.util.*; | ||||||
| import java.util.function.Function; |  | ||||||
| import java.util.function.Predicate; | import java.util.function.Predicate; | ||||||
| import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||||
| 
 | 
 | ||||||
|  | @ -30,7 +29,6 @@ import ch.ethz.seb.sebserver.gbl.Constants; | ||||||
| import ch.ethz.seb.sebserver.gbl.api.API; | import ch.ethz.seb.sebserver.gbl.api.API; | ||||||
| import ch.ethz.seb.sebserver.gbl.api.API.BulkActionType; | import ch.ethz.seb.sebserver.gbl.api.API.BulkActionType; | ||||||
| import ch.ethz.seb.sebserver.gbl.api.EntityType; | import ch.ethz.seb.sebserver.gbl.api.EntityType; | ||||||
| import ch.ethz.seb.sebserver.gbl.model.Domain; |  | ||||||
| import ch.ethz.seb.sebserver.gbl.model.EntityDependency; | import ch.ethz.seb.sebserver.gbl.model.EntityDependency; | ||||||
| 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; | ||||||
|  | @ -58,8 +56,6 @@ public class ClientConnectionController extends ReadonlyEntityController<ClientC | ||||||
| 
 | 
 | ||||||
|     private final SEBClientSessionService sebClientSessionService; |     private final SEBClientSessionService sebClientSessionService; | ||||||
| 
 | 
 | ||||||
|     private static final Set<String> EXT_FILTER = new HashSet<>(Arrays.asList(ClientConnection.FILTER_ATTR_INFO)); |  | ||||||
| 
 |  | ||||||
|     protected ClientConnectionController( |     protected ClientConnectionController( | ||||||
|             final AuthorizationService authorization, |             final AuthorizationService authorization, | ||||||
|             final BulkActionService bulkActionService, |             final BulkActionService bulkActionService, | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 anhefti
						anhefti