Skip to content

Commit

Permalink
SEBSERV-587 User Account sync improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
anhefti committed Oct 1, 2024
1 parent bdda9e2 commit 5996604
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AdHocAccountData;
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.TeacherAccountService;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.ExamDAO;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserDAO;
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ScreenProctoringService;
import ch.ethz.seb.sebserver.webservice.weblayer.oauth.AdminAPIClientDetails;
Expand Down Expand Up @@ -188,8 +187,14 @@ public Result<TokenLoginInfo> verifyOneTimeTokenForTeacherAccount(final String l
public void deleteAllFromLMS(final Long lmsId) {
userDAO
.deleteAdHocAccountsForLMS(AD_HOC_TEACHER_ID_PREFIX, lmsId)
.map(this::deleteAccountsOnSPS)
.onError(error -> log.error("Failed to delete all teacher accounts for LMS with id: {}", lmsId, error));
}

private Collection<EntityKey> deleteAccountsOnSPS(final Collection<EntityKey> keys) {
keys.forEach(key -> this.screenProctoringService.deleteSPSUser(key.modelId) );
return keys;
}

private UserInfo handleAccountDoesNotExistYet(
final boolean createIfNotExists,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public interface ScreenProctoringGroupDAO {
*
* @param pk the group identifier (PK)
* @return Result refer to the entity key of the former group record or to an error when happened */
Result<EntityKey> deleteRoom(Long pk);
Result<EntityKey> deleteGroup(Long pk);

/** Delete all groups records for a given exam.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ public Result<ScreenProctoringGroup> createNewGroup(final ScreenProctoringGroup

@Override
@Transactional
public Result<EntityKey> deleteRoom(final Long pk) {
public Result<EntityKey> deleteGroup(final Long pk) {
return Result.tryCatch(() -> {

this.screenProctoringGroopRecordMapper
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,22 +103,6 @@ public Result<ScreenProctoringSettings> getScreenProctoringSettings(final Entity
return this.proctoringSettingsDAO
.getScreenProctoringSettings(parentEntityKey)
.getOrThrow();

// if (this.screenProctoringServiceBundle.bundled) {
// settings = new ScreenProctoringSettings(
// settings.examId,
// settings.enableScreenProctoring,
// this.screenProctoringServiceBundle.serviceURL,
// this.screenProctoringServiceBundle.clientId,
// null,
// this.screenProctoringServiceBundle.apiAccountName,
// null,
// settings.collectingStrategy,
// settings.collectingGroupSize,
// true);
// }
//
// return settings;
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ default void processSessionUpdateTask() {
updateClientConnections();
updateActiveGroups();
}

boolean isScreenProctoringEnabled(Long examId);

/** This is testing the given ScreenProctoringSettings on integrity and if we can
* connect to the given SEB screen proctoring service.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class ScreenProctoringAPIBinding {

private static final String SEB_SERVER_SCREEN_PROCTORING_SEB_ACCESS_PREFIX = "SEBServer_SEB_Access_";

static interface SPS_API {
interface SPS_API {

enum SPSUserRole {
ADMIN,
Expand All @@ -86,7 +86,7 @@ enum SPSUserRole {

String USER_ACCOUNT_ENDPOINT = "/admin-api/v1/useraccount/";
String USERSYNC_SEBSERVER_ENDPOINT = USER_ACCOUNT_ENDPOINT + "usersync/sebserver";
String ENTITY_PRIVILEGES_ENDPOINT = USER_ACCOUNT_ENDPOINT + "entityprivilege";
// String ENTITY_PRIVILEGES_ENDPOINT = USER_ACCOUNT_ENDPOINT + "entityprivilege";
String EXAM_ENDPOINT = "/admin-api/v1/exam";
String EXAM_DELETE_REQUEST_ENDPOINT = "/request";
String SEB_ACCESS_ENDPOINT = "/admin-api/v1/clientaccess";
Expand All @@ -96,19 +96,19 @@ enum SPSUserRole {
String INACTIVE_PATH_SEGMENT = "/inactive";


interface ENTITY_PRIVILEGE {
String ATTR_ENTITY_TYPE = "entityType";
String ATTR_ENTITY_ID = "entityId";
String ATTR_USER_UUID = "userUuid";
String ATTR_USERNAME = "username";
String ATTR_PRIVILEGES = "privileges";
}

interface PRIVILEGE_FLAGS {
String READ = "r";
String MODIFY = "m";
String WRITE = "w";
}
// interface ENTITY_PRIVILEGE {
// String ATTR_ENTITY_TYPE = "entityType";
// String ATTR_ENTITY_ID = "entityId";
// String ATTR_USER_UUID = "userUuid";
// String ATTR_USERNAME = "username";
// String ATTR_PRIVILEGES = "privileges";
// }
//
// interface PRIVILEGE_FLAGS {
// String READ = "r";
// String MODIFY = "m";
// String WRITE = "w";
// }

/** The screen proctoring service client-access API attribute names */
interface SEB_ACCESS {
Expand Down Expand Up @@ -435,6 +435,8 @@ void deleteSPSUser(final String userUUID) {

if (exchange.getStatusCode() == HttpStatus.OK) {
log.info("Successfully deleted User Account on SPS for user: {}", userUUID);
} else if (exchange.getStatusCode() == HttpStatus.NOT_FOUND) {
log.info("SPS User with uuid {} not found on SPS site.", userUUID);
} else {
log.error("Failed to delete user account on SPS for user: {} response: {}", userUUID, exchange);
}
Expand Down Expand Up @@ -664,7 +666,6 @@ Collection<ScreenProctoringGroup> reinitializeScreenProctoring(final Exam exam)
log.error("Failed to re-initialize Screen Proctoring: ", e);
return Collections.emptyList();
}

}

Result<ScreenProctoringGroup> createGroup(
Expand Down Expand Up @@ -930,7 +931,7 @@ private Collection<ScreenProctoringGroup> initializeGroups(
boolean applyRollback) {

try {

final ScreenProctoringSettings settings = this.proctoringSettingsDAO
.getScreenProctoringSettings(new EntityKey(exam.id, EntityType.EXAM))
.getOrThrow();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import static ch.ethz.seb.sebserver.gbl.model.session.ClientInstruction.SEB_INSTRUCTION_ATTRIBUTES.SEB_SCREEN_PROCTORING.*;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import ch.ethz.seb.sebserver.gbl.async.AsyncServiceSpringConfig;
import ch.ethz.seb.sebserver.gbl.model.Activatable;
Expand Down Expand Up @@ -56,6 +58,8 @@
public class ScreenProctoringServiceImpl implements ScreenProctoringService {

private static final Logger log = LoggerFactory.getLogger(ScreenProctoringServiceImpl.class);
public static final Logger INIT_LOGGER = LoggerFactory.getLogger("ch.ethz.seb.SEB_SERVER_INIT");

private final Cryptor cryptor;
private final ScreenProctoringAPIBinding screenProctoringAPIBinding;
private final ScreenProctoringGroupDAO screenProctoringGroupDAO;
Expand Down Expand Up @@ -185,8 +189,8 @@ public Result<Exam> applyScreenProctoringForExam(final EntityKey entityKey) {
"Failed to apply screen proctoring for exam: {}",
exam,
error))
.getOrThrow()
.forEach(newGroup -> createNewLocalGroup(exam, newGroup));
.map(groups -> createExamGroups(exam, groups))
.getOrThrow();

this.examDAO.markUpdate(exam.id);

Expand All @@ -204,6 +208,34 @@ public Result<Exam> applyScreenProctoringForExam(final EntityKey entityKey) {
return exam;
});
}

private Exam createExamGroups(final Exam exam, final Collection<ScreenProctoringGroup> groups) {

final Map<String, ScreenProctoringGroup> existingGroups = this.screenProctoringGroupDAO
.getCollectingGroups(exam.id)
.onError(error -> log.error("Failed to get existing groups to check integrity: ", error))
.getOr(Collections.emptyList())
.stream().collect(Collectors.toMap( g -> g.name, Function.identity()));

groups.forEach(newGroup ->
{
if (existingGroups.containsKey(newGroup.name)) {
final ScreenProctoringGroup screenProctoringGroup = existingGroups.get(newGroup.name);

log.warn(
"There exists already a local screen proctoring group with the name: {}. This is deleted due to the fact that a new one is going to be created with the same name. Groups {}",
screenProctoringGroup.name,
screenProctoringGroup);

this.screenProctoringGroupDAO.deleteGroup(screenProctoringGroup.id)
.onError(error -> log.error("Failed to delete screen proctoring group due to group mismatch", error));
}

createNewLocalGroup(exam, newGroup);
});

return exam;
}

@Override
public Result<Collection<ScreenProctoringGroup>> getCollectingGroups(final Long examId) {
Expand Down Expand Up @@ -460,7 +492,6 @@ private ScreenProctoringGroup applySEBConnectionToGroup(
return applyToDefaultGroup(ccRecord.getId(), ccRecord.getConnectionToken(), exam);
}
}

}

private ScreenProctoringGroup applyToDefaultGroup(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import ch.ethz.seb.sebserver.webservice.servicelayer.session.ScreenProctoringService;
import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationService;
import ch.ethz.seb.sebserver.webservice.weblayer.oauth.RevokeTokenEndpoint;
import com.sun.xml.bind.v2.TODO;
import org.mybatis.dynamic.sql.SqlTable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down

0 comments on commit 5996604

Please sign in to comment.