From 64e1b0d03db4a70872ddea7fae1b672a5c40278a Mon Sep 17 00:00:00 2001 From: anhefti Date: Tue, 17 Mar 2020 10:24:11 +0100 Subject: [PATCH] docu, unique email check on user-account, wording --- docs/images/account/registered.png | Bin 0 -> 40678 bytes docs/institution.rst | 2 +- docs/useraccount.rst | 64 ++++++++++++++++-- .../servicelayer/dao/impl/UserDAOImpl.java | 22 ++++++ src/main/resources/messages.properties | 25 +++---- 5 files changed, 94 insertions(+), 19 deletions(-) create mode 100644 docs/images/account/registered.png diff --git a/docs/images/account/registered.png b/docs/images/account/registered.png new file mode 100644 index 0000000000000000000000000000000000000000..ab28528d1fe4659e1fbb5a151f37fa938fc904f9 GIT binary patch literal 40678 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 DiCT_5 literal 0 HcmV?d00001 diff --git a/docs/institution.rst b/docs/institution.rst index 3cc91ec1..4c31313a 100644 --- a/docs/institution.rst +++ b/docs/institution.rst @@ -5,7 +5,7 @@ The institution section within SEB Server is used to support built-in multi-tena light-weight stand-alone server but with the possibility to separate operation completely within different institutions. .. note:: - If a quick use-case based reference suites you better, just forward to the "Use Cases" section of this chapter + If a quick use-case based reference suites you better, just forward to the "Use Cases" section of this chapter below Only the role of SEB Server administrator and institutional administrator are able to see and use this section. A SEB Server administrator is able to see the whole list of all existing institutions and to create new and maintain every diff --git a/docs/useraccount.rst b/docs/useraccount.rst index 500f2b7b..4c318cd6 100644 --- a/docs/useraccount.rst +++ b/docs/useraccount.rst @@ -4,6 +4,9 @@ User Accounts The user-account section within SEB Server can be used to create new or modify user-accounts for other user or to modify the own user account and changing the password. This section differs most for the different roles in SEB Server. +.. note:: + If a quick use-case based reference suites you better, just forward to the "Use Cases" section of this chapter below + A user account always belongs to one institution and has some basic attributes; - Institution: A combo- or single-selection to choose the institution the user account belongs to. This is mandatory @@ -28,10 +31,59 @@ A user account always belongs to one institution and has some basic attributes; For more information about roles and each role see the section :ref:`roles_and_usecases` By selecting the "User Account" section on the left side menu, a SEB Server administrator will see a list of all user-accounts -of all institution within a SEB Server instance. The filter above the list can be used to search a certain user account. +of all institution within a SEB Server instance. The filter above the list can be used to search a certain user account. Use the: -- Use the "Institution" filter to select a certain institution and show only the user-accounts that belongs to this institution. -- Use the "First Name" filter to search for user-accounts with the given occurrence of text in the First Name. -- Use the "User Name" filter to search for user-accounts with the given occurrence of text in the Username. -- Use the "Mail" filter to find an user-account by e-mail address -- \ No newline at end of file +- "Institution" filter to select a certain institution and show only the user-accounts that belongs to this institution. +- "First Name" filter to search for user-accounts with the given occurrence of text in the First Name. +- "User Name" filter to search for user-accounts with the given occurrence of text in the Username. +- "Mail" filter to find an user-account by e-mail address +- "Status" filter to select the either and see either only active, only inactive or all user-accounts + +.. image:: images/account/list_serveradmin.png + :align: center + :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/account/list_serveradmin.png + +To view all information of a user-account, double-click in a certain user-account entry from the list or select an entry from the list and +use the "View User Account" action on the right action pain. The user account form will be shown in read only mode with all account information. +To edit this user-account use the "Edit User Account" action on the right action pane. To change the password of the user + + +Use Cases +--------- + +**Register as a exam supporter** + +Registering as a new user is possible only within the SEB Server form-registration yet. Since the SEB Server is mainly a service for administrative work, +there is no third party registration and login in place so far. A self-registered user-account has the single role of an +Exam Supporter and since this user-account is not applied to an exiting exam and running, the user is only able to see and edit its own account settings. +Another user with Exam Administrator role can then assign the new user-account to an exam for support and monitoring. Or one other user-account with +Institution Administrator role can edit the new user-account and give it more privileges. + +To register a new user-account follow the steps below + +- Use a Web-Browser and go to the SEB Server login page by entering the SEB Server URL. +- Click the "Register" action on the login page that is shown right after the "Sign In" action. +- The application will show the registration form. See the image below. +- Enter all mandatory account data within the form and use the "Register" action to confirm. +- If there is missing or wrong data, the registration form will highlight the concerned input fields with a red border and information text just below the field. +- If everything is accepted the user-account is created and the application forwards automatically to the login page. +- Sign in with the user credentials to check the account works correctly. + +.. image:: images/overview/register.png + :align: center + :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/overview/register.png + +Once signed in, the user can see all sections for a Exam Administrator as shown in the image below. Because the user is not assigned to any +Exam as a supporter yet, the "Exam Administration" and "Monitoring" sections are empty. The user is only able to change the account settings. + +.. image:: images/account/registered.png + :align: center + :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/account/registered.png + +**Create new user-account** + +**Modify user-account** + +**Change password** + +**Activate / Deactivate user-account \ No newline at end of file diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDAOImpl.java index d1e89e5c..860405d9 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/UserDAOImpl.java @@ -201,6 +201,7 @@ public class UserDAOImpl implements UserDAO { } checkUniqueUsername(userMod); + checkUniqueMailAddress(userMod); final UserRecord recordToSave = new UserRecord( null, @@ -260,6 +261,7 @@ public class UserDAOImpl implements UserDAO { .map(record -> { checkUniqueUsername(userInfo); + checkUniqueMailAddress(userInfo); final UserRecord newRecord = new UserRecord( record.getId(), @@ -505,4 +507,24 @@ public class UserDAOImpl implements UserDAO { } } + private void checkUniqueMailAddress(final UserAccount userAccount) { + if (StringUtils.isBlank(userAccount.getEmail())) { + return; + } + + // check same username already exists + final Long otherUsersWithSameName = this.userRecordMapper + .countByExample() + .where(UserRecordDynamicSqlSupport.email, isEqualTo(userAccount.getEmail())) + .and(UserRecordDynamicSqlSupport.uuid, isNotEqualToWhenPresent(userAccount.getModelId())) + .build() + .execute(); + + if (otherUsersWithSameName != null && otherUsersWithSameName > 0) { + throw new APIMessageException(APIMessage.fieldValidationError( + Domain.USER.ATTR_EMAIL, + "user:email:email.notunique")); + } + } + } diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index f661c3ca..4c8406f0 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -81,6 +81,7 @@ sebserver.form.validation.fieldError.urlSuffix=The URL Suffix must have a size b sebserver.form.validation.fieldError.notNull=This field is mandatory sebserver.form.validation.fieldError.name.notunique=This name is already in use. Please choose another one. sebserver.form.validation.fieldError.username.notunique=This Username is already in use. Please choose another one. +sebserver.form.validation.fieldError.email.notunique=A user-account with this e-mail address already exists. sebserver.form.validation.fieldError.password.wrong=The old password is wrong sebserver.form.validation.fieldError.password.mismatch=The re-typed password doesn't match the new password sebserver.form.validation.fieldError.invalidURL=The input does not match the URL pattern. @@ -138,7 +139,7 @@ sebserver.actionpane.title= ################################ sebserver.institution.list.actions= -sebserver.institution.list.empty=No institution has been found. Please adapt the filter or create a new institution +sebserver.institution.list.empty=No institution can be found. Please adapt the filter or create a new institution sebserver.institution.list.title=Institutions sebserver.institution.list.title.subtitle= sebserver.institution.list.column.name=Name @@ -188,7 +189,7 @@ sebserver.useraccount.role.EXAM_ADMIN.tooltip=An exam administrator has overall sebserver.useraccount.role.EXAM_SUPPORTER=Exam Supporter sebserver.useraccount.role.EXAM_SUPPORTER.tooltip=An exam supporter can only see and edit the own user account
and monitor exams for that he/she was attached by an exam administrator. -sebserver.useraccount.list.empty=No user account has been found. Please adapt the filter or create a new user account +sebserver.useraccount.list.empty=No user account can be found. Please adapt the filter or create a new user account sebserver.useraccount.list.title=User Accounts sebserver.useraccount.list.title.subtitle= sebserver.useraccount.list.column.institution=Institution @@ -260,7 +261,7 @@ sebserver.lmssetup.type.OPEN_EDX=Open edX sebserver.lmssetup.list.actions= 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 can be found. Please adapt the filter or create a new LMS Setup sebserver.lmssetup.list.title=Learning Management System Setups sebserver.lmssetup.list.title.subtitle=List of connection settings to the LMS. sebserver.lmssetup.list.column.institution=Institution @@ -282,7 +283,7 @@ sebserver.lmssetup.action.savetest=Test And Save sebserver.lmssetup.action.testsave=Test And Save sebserver.lmssetup.action.test.ok=Successfully connected to the course API sebserver.lmssetup.action.test.tokenRequestError=The API access was denied: {0}
Please check the LMS connection details. -sebserver.lmssetup.action.test.quizRequestError=Unable to request courses or quizzes from the course API of the LMS. {0} +sebserver.lmssetup.action.test.quizRequestError=Unable to request courses or exams from the course API of the LMS. {0} sebserver.lmssetup.action.test.quizRestrictionError=Unable to access course restriction API of the LMS. {0} sebserver.lmssetup.action.test.missingParameter=There is one or more missing connection parameter.
Please check the connection parameter for this LMS Setup sebserver.lmssetup.action.test.unknownError=An unexpected error happened while trying to connect to the LMS course API. {0} @@ -330,7 +331,7 @@ sebserver.quizdiscovery.list.actions= sebserver.quizdiscovery.list.title=LMS Exams sebserver.quizdiscovery.list.title.subtitle=List of exams found in connected LMS. -sebserver.quizdiscovery.list.empty=No LMS exam has been found. Please adapt the filter or create a new LMS Setup +sebserver.quizdiscovery.list.empty=No LMS exam can be found. Please adapt the filter or create a new LMS Setup sebserver.quizdiscovery.list.column.institution=Institution sebserver.quizdiscovery.list.column.institution.tooltip=The institution filter.

Use the filter above to specify the institution.
{0} sebserver.quizdiscovery.list.column.lmssetup=LMS @@ -341,7 +342,7 @@ sebserver.quizdiscovery.list.column.starttime=Start Time {0} sebserver.quizdiscovery.list.column.starttime.tooltip=The start time of the LMS exam.

Use the filter above to set a specific from date.
{0} sebserver.quizdiscovery.list.column.endtime=End Time {0} sebserver.quizdiscovery.list.column.endtime.tooltip=The end time of the LMS exam.

{0} -sebserver.quizdiscovery.info.pleaseSelect=Please select first a Quiz from the list +sebserver.quizdiscovery.info.pleaseSelect=Please select first an LMS exam from the list sebserver.quizdiscovery.action.list=LMS Exam Lookup sebserver.quizdiscovery.action.import=Import as Exam @@ -394,7 +395,7 @@ sebserver.exam.list.column.starttime.tooltip=The start time of the exam.


Use the filter above to set a specific exam type.
{0} -sebserver.exam.list.empty=No Exam has been found. Please adapt the filter or import one from Quiz +sebserver.exam.list.empty=No Exam can be found. Please adapt the filter or import one from LMS sebserver.exam.list.modify.out.dated=Finished exams cannot be modified. sebserver.exam.list.action.no.modify.privilege=No Access: An Exam from other institution cannot be modified. @@ -424,10 +425,10 @@ sebserver.exam.form.title=Exam sebserver.exam.form.title.subtitle= sebserver.exam.form.lmssetup=LMS Setup sebserver.exam.form.lmssetup.tooltip=The LMS setup that defines the LMS of the exam. -sebserver.exam.form.quizid=Quiz Identifier +sebserver.exam.form.quizid=LMS exam Identifier sebserver.exam.form.quizid.tooltip=The identifier that identifies the quiz of the exam on the corresponding LMS -sebserver.exam.form.quizurl=Quiz URL -sebserver.exam.form.quizurl.tooltip=The direct URL link to the quiz/exam on the LMS +sebserver.exam.form.quizurl=LMS exam URL +sebserver.exam.form.quizurl.tooltip=The direct URL link to the LMS exam sebserver.exam.form.name=Name sebserver.exam.form.name.tooltip=The name of the exam.

This name is defined on the corresponding LMS sebserver.exam.form.description=Description @@ -1400,12 +1401,12 @@ sebserver.userlogs.form.message.tooltip=The user activity log message.
This sebserver.userlogs.details.title=User Activity Log Details sebserver.userlogs.info.pleaseSelect=Please select first a User Log from the list sebserver.userlogs.list.actions= -sebserver.userlogs.list.empty=No User activity logs has been found. Please adapt or clear the filter +sebserver.userlogs.list.empty=No User activity logs can be found. Please adapt or clear the filter sebserver.seblogs.list.title=SEB Client Logs sebserver.seblogs.list.actions= -sebserver.seblogs.list.empty=No SEB client logs has been found. Please adapt or clear the filter +sebserver.seblogs.list.empty=No SEB client logs available. Please adapt or clear the filter sebserver.seblogs.info.pleaseSelect=Please select first a SEB client Log from the list sebserver.seblogs.list.column.institution=Institution