From d01b01d7992aabf824a0c612329f9c07f4e31ad8 Mon Sep 17 00:00:00 2001 From: anhefti Date: Mon, 8 May 2023 20:21:18 +0200 Subject: [PATCH 01/31] foxed docu --- docs/requirements.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index c896d4df..eb2a5188 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1,5 @@ -docutils<0.18 \ No newline at end of file +docutils<0.18 +sphinx==5.3.0 +sphinx_rtd_theme==1.1.1 +readthedocs-sphinx-search==0.1.1 +urllib3==1.26.13 \ No newline at end of file From dcbb2790522cded5692c37a739f8d5afaf65222f Mon Sep 17 00:00:00 2001 From: anhefti Date: Mon, 8 May 2023 21:44:12 +0200 Subject: [PATCH 02/31] update README --- README.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 9d34656a..27ff11ae 100644 --- a/README.rst +++ b/README.rst @@ -98,7 +98,8 @@ Bugfixes: Docker-Image: -TODO +- Exact release version: docker pull anhefti/seb-server:v1.5.0 (sha256:21d62e24dd5cf697ab5f2b437dc458e6c7492ea294f77a424d39d05164d6c8cc) +- Latest stable minor version with patches: docker pull anhefti/seb-server:v1.5-stable SEB - SEB Server Compatibility From 659ad0e9ffa2d79e1630306b401f8fab42dfab15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luca=20B=C3=B6sch?= Date: Mon, 15 May 2023 12:26:58 +0200 Subject: [PATCH 03/31] Moodle plugin repository renamed. --- README.rst | 2 +- docs/lmssetup.rst | 530 +++++++++++++++++++++++----------------------- 2 files changed, 266 insertions(+), 266 deletions(-) diff --git a/README.rst b/README.rst index 27ff11ae..87b3fcfe 100644 --- a/README.rst +++ b/README.rst @@ -62,7 +62,7 @@ New Features: - Security: New Application Signature Key (ASK) integration within SEB Server exams and monitoring - Security: Minimum SEB Client version tracking within SEB Server monitoring -- LMS Integration: Better Moodle integration with new `SEB Server Moodle Plugin `_ +- LMS Integration: Better Moodle integration with new `SEB Server Moodle Plugin `_ - Exam Maintenance: Added new SEB grouping functionality for Exam (and Exam Template) and Monitoring to be able to view/manage SEB Clients within defined groups (IP range, SEB client OS, ...) - Exam Maintenance: Batch actions for archive and delete exams - Exam Maintenance: Added SEB log export for finished and archived exams diff --git a/docs/lmssetup.rst b/docs/lmssetup.rst index 69923fd3..e29d10c6 100644 --- a/docs/lmssetup.rst +++ b/docs/lmssetup.rst @@ -1,265 +1,265 @@ -.. _lms-setup-label: - -Learning Management System Setup -================================ - -Overview --------- - -To be able to connect to a learning management system (LMS), to view and manage the courses provided by a LMS is an essential feature of the SEB Server. -To setup an exam or e-assessment for SEB on SEB Server that is based on a course from a LMS, we have to make a binding to the course on the LMS. -This is also used to always get the actual course data from LMS like start- end-time, name and others. -Another feature of SEB Server that needs a LMS communication is the SEB restriction. A SEB restriction will restrict course access on the LMS only -for connection with Safe Exam Browser and will also check if a Safe Exam Browser of trust is used and the right configuration is used by the -Safe Exam Browser that was defines for the exam on the SEB Server. - -**Course API** - -This API, provided by the LMS, is used by the SEB Server to query the available courses and the needed data for each course. This API -is needed to be able to import a course from the LMS as an exam into SEB Server and configure the course as an e-assessment with SEB. -Usually this API comes as a REST or SOAP API with the core LMS implementation or a plugin. - -SEB Server supports this course API's so far: - - Open edX: The standard system `Open edX REST API `_. The SEB Server uses the "courses" endpoints to get course data. - - Moodle (Course Access): The standard system `Moodle REST API `_. The SEB Server uses the standard Moodle rest endpoints to get course data. - Please note that a second Moodle integration part for SEB access restriction with Config-Key will follow together with a Moodle plugin in a future version of SEB Server - - -**SEB Restriction API** - -If the automated SEB restriction functionality is available for a LMS depends on the following requirements: - -- There must exist a SEB integration plugin that offers an API to put and pull SEB restrictions in the form of Config-Keys and/or Browser-Exam-Keys - To the LMS and a specific course on the LMS to restrict the access. Such a plugin may also offer additional restriction features like restricting - on course section or course components or only for specified user roles. -- The SEB integration plugin must be installed on the LMS that is used by the SEB Server. - -For more information about known SEB integration plugins that are supported by the SEB Server see :ref:`lms-setup-rest-plugin-label` - -Regardless if a supported LMS is missing the SEB integration plugin installation, the LMS can be used with the Course API and an exam -setup will be possible but without automated SEB restriction feature. - -To be able to connect to an LMS from SEB Server, we need to create an API access account on the LMS side that can be used by the SEB Server to -access the API of the LMS. How to do this for the different supported types of LMS see :ref:`lms-api-account-label`. -After such an account was created, the account credentials, username and password, can be used by the SEB Server to connect to the LMS. -Therefore we need to create a LMS Setup on the SEB Server. - -.. image:: images/lmssetup/new.png - :align: center - :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/lmssetup/new.png - -A SEB Server administrator role will be able to see the institution to which the LMS Setup belongs to while an institutional administrator -is only able to see and create LMS Setup for its own institution. The name of the LMS Setup should be unique and is to identify a LMS -SEB Server internally. Use the **"Type"** selector to specify the type of the LMS to bind to the SEB Server within the LMS Setup. Currently supported are: - -- **Testing**: This is for testing purposes only and can be used to mock a LMS to test exam settings. This type provides some mock-up courses within the - LMS API of the SEB Server that can be seen in the LMS Exam Lookup once the LMS text setup is active. This mock-up courses can be imported and configured - as exams like they would exist. But note the a SEB client that is trying to connect to such a course would not be able to connect to the LMS since it - is not existing. But a SEB client is able to download the defined exam configuration for testing. -- **Open edX**: This type is to bind an existing `Open edX `_ LMS system that is available on the Internet or intranet. The SEB - Server tries to make use of the above described API's of the Open edX system. - - .. note:: - If you want to use the automated SEB restriction feature too, the `Open edX SEB Plugin `_ must be installed properly on the LMS. - -- **Moodle**: This type is to bind an existing `Moodle `_ LMS system that is available on the Internet or intranet. The SEB - Server tries to make use of the described API's of the Moodle system but there is currently no SEB restriction plugin available that works - with SEB Server. Note that Moodle integration is implemented partially within SEB Server version 1.1.x. Only the course access feature is implemented and the course restriction feature will come with a future SEB Server release - -- **Moodle with SEB Server Plugin**: The `SEB Server Plugin for Moodle `_ is new and supported by SEB Server since version 1.5. - With this plugin installed on Moodle side, SEB Server is able to more efficiently communicate with Moodle to fetch course data as well as restricting the quiz on Moodle side - For SEB only access, using a auto-generated Browser Exam Key (BEK) for SEB restriction. Also the Moodle user name resolving for SEB Server monitoring is less error prone especially - if Single Sign On some kind of login provider for Moodle is involved. Furthermore the new SEB Server Plugin for Moodle will be constantly extended and improved with new features in the future. - -- **Ans Delft**: This type is to bind SEB Server with an `Ans Delft `_ LMS. With the API credentials from an Ans Delft instance, SEB Server is able - to connect to the Ans LMS and provide the common features for Course-Access, SEB Restriction and LMS User Session resolving. - -- **Open Olat**: This type is to bind SEB Server with an `Open Olat `_ LMS. With the API credentials from an Open Olat instance, SEB Server is able - to connect to the Olat LMS and provide the common features for Course-Access, SEB Restriction and LMS User Session resolving. For more information please contact the Olat Development-Team at `OpenOLAT UZH `_ - -The **"LMS Server Address"** is the root URL to connect to the LMS server with HTTP over the Internet or intranet. This is usually the URL that is -also used with the Browser to connect to the main page of the LMS system. And additionally the credentials that have been created with the creation of the :ref:`lms-api-account-label` has to be set in the LMS Setup the make the SEB Server -able to securely connect to the LMS. The API credentials that consists of a client-name and a client-secret must be used with the **"LMS Server Username"** -and the **"LMS Server Password"** fields of the LMS Setup form on SEB Server. - -Alternatively to **"LMS Server Username"** and **"LMS Server Password"** you can use a direct **Access Token** to connect to the LMS API if the respective LMS allows to -generate and use an access token directly. - -If the SEB Server running behind a proxy server or a firewall between SEB Server den LMS, the additional proxy settings can be used to setup the proxy-connection. - -.. note:: - To Setup a Test LMS Setup (of type "Test") only a correct URL pattern must be set like "http://test" for example. And API credentials can be anything but must be set. - -After all the settings for a LMS Setup have been set, one can use either the "Save LMS Setup" action to save the LMS Setup without activation or the -"Activate LMS Setup" action to also activate the settings right after they has been successfully saved. Anyway, for both action there is an initial test -that, additionally to the usual field validation that takes place first, tries to connect to the LMS with the given API details. If the connection -wasn't successful, the SEB Server will inform the user about a possible reason of failure. Otherwise SEB Server shows a success message and the created -LMS Setup can be used. - -Use the "Activate / Deactivate LMS Setup" action to activate an inactive LMS Setup or the deactivate an active LMS Setup. - -.. note:: - On deactivation of an LMS Setup, the system checks on depending object and will show a confirmation to the user asking that all depending - objects will also been deactivated. Depending objects of an LMS Setup are exams that has been imported from the specified LMS Setup in the past. - - -Use Cases ---------- - -**Create a new LMS Setup for Open edX** - -A new Open edX system has been installed within your institution and to be able to use the system also for e-assessments with SEB and SEB Server, -you have to bind the LMS to the SEB Server. - -- If not already done, install the `Open edX SEB Plugin `_ on the Open edX system first. -- If you don't already have an API access account on Open edX side, `create one `_ -- Sign into SEB Server with your institutional administrator role account. -- Navigate to "Exam Administration" / "LMS Setup" within the navigation on the left hand side. -- Use the "Add LMS Setup" action from the right action pane to open a LMS Setup creation form. -- Give a unique name to the new LMS Setup for internally identification. -- Set the main URL that points to the new LMS system. This is usually the URL that is also used with the Browser to connect to the main page of the LMS system -- Set the API credentials that has been creates within step two (client-id, secret). -- Use the "Activate LMS Setup" action on the right action pane to test, save and activate the new LMS Setup within one step. - -.. note:: - If some form attributes are missing or not correct, the SEB Server system will respond with the usual form validation errors. - If the connection to the LMS is failing because of missing or wrong credentials or for any other reason the system is not able to connect to the LMS - the SEB Server will notify an error dialog to the user. - - -**Change API Credentials of an Active LMS Setup** - -The API access account on the LMS has been expired and you have to create a new one or update the old one which both result in new API access credentials -that has to be set on the existing LMS Setup on the SEB Server. - -.. image:: images/lmssetup/list.png - :align: center - :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/lmssetup/list.png - -- Sign into SEB Server with your institutional administrator role account. -- Navigate to "Exam Administration" / "LMS Setup" within the navigation on the left hand side. -- Use the Filter above the list to find the specified LMS Setup. -- Select the LMS Setup from the list and use the "Edit LMS Setup" action from the right action pane to open the LMS Setup in edit mode. -- Set the new credentials and make sure, the LMS Setup is still active. -- Use the "Save LMS Setup" action form the right action pane to save the changes and test the connection. - -.. note:: - If some form attributes are missing or not correct, the SEB Server system will respond with the usual form validation errors. - If the connection to the LMS is failing because of missing or wrong credentials or for any other reason the system is not able to connect to the LMS - the SEB Server will notify an error dialog to the user. - -**Deactivate LMS Setup** - -A LMS system that was running on your campus to provide e-assessment with SEB and SEB Server has been shut down and you need to also deactivate -the setup and exams on the SEB Server for this LMS. - -- Sign into SEB Server with your institutional administrator role account. -- Navigate to "Exam Administration" / "LMS Setup" within the navigation on the left hand side. -- Use the Filter above the list to find the specified LMS Setup. -- Select the specified LMS Setup from the list and use the "Deactivate LMS Setup" action from the right action pane. -- Alternatively you can also double-click on the LMS Setup to fist go into the detailed view of the LMS setup and use the "Deactivate LMS Setup" action there. -- The system informs you about the number of depending exams that also will be deactivated within the deactivation of the LMS Setup. -- Confirm the deactivation and notify that the LMS Setup now is listed as "Inactive" in the list. -- Navigate to "LMS Exam Lookup" to make sure the courses form the deactivated LMS Setup are not available anymore. -- Navigate also to "Exam" and make sure that all previously imported exams from the deactivated LMS Setup are not available anymore. - -.. _lms-api-account-label: - -API Access Account on LMS --------------------------- - -.. _lms-api-account-edx-label: - -**Create Open edX API Access Account** - -To be able to create an API access-account on Open edX you need a user-account with staff and administration privileges. - -**For Open edX Hawthorn and Ironwood versions following the steps below::** - -- Login to Open edX LMS Administration with an appropriate user-account that has administration rights. And find the Users section: - -.. image:: images/lmssetup/openEdxAPIAccess1.bmp - :align: center - :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/lmssetup/openEdxAPIAccess1.bmp - -- Create a new User-Account that acts as an API account. The account must at least have the permissions to query the course API of Open edX and to access the seb_openedx plugin permission. -- Make sure that "Staff" status is checked for the account. - -.. image:: images/lmssetup/openEdxAPIAccess2.bmp - :align: center - :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/lmssetup/openEdxAPIAccess2.bmp - -- Back in the administration homepage, find the OAUT2 - Client section and create a new API Client Access for the given User-Account. The Client id and Client secret are automatically generated by Open edx. - -.. image:: images/lmssetup/openEdxAPIAccess3.bmp - :align: center - :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/lmssetup/openEdxAPIAccess3.bmp - -.. image:: images/lmssetup/openEdxAPIAccess4.bmp - :align: center - :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/lmssetup/openEdxAPIAccess4.bmp - -Once the client registration was successful the client id and client secret can be used within the SEB Server to access the course- and SEB-restriction API of Open edX as described in the next step section - -.. note:: - Since Open edX Juniper is using Django Oauth Toolkit instead of Django Oauth Provider the last step in the above guide looks slightly different. Please see below the last step for setting up on an Open edX Juniper version. - -- Back in the administration homepage, find the DJANGO OAUTH TOOLKIT - Applications section and create a new API Application Access for the given User-Account. The Client id can be defined and the Client secret is automatically be generated by Open edx. - -.. image:: images/lmssetup/openEdxAPIAccess5.png - :align: center - :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/documentation/docs/images/lmssetup/openEdxAPIAccess5.png - -.. image:: images/lmssetup/openEdxAPIAccess6.png - :align: center - :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/documentation/docs/images/lmssetup/openEdxAPIAccess6.png - - - -**Create Moodle API Access Account** - -To be able to create an LMS Setup for Moodle you need a Moodle administrator or manager account. You can then use this account in the LMS Setup to connect to the LMS. - -Since SEB Server uses some functions from the Moodle's mobile API, you have to make sure the web services for mobile apps are enabled within your Moodle setup. -To do so please login to Moodle with an administrator account and go to "Side Administration", scroll down to "Mobile App" and choose "Mobile Settings. - -.. image:: images/lmssetup/moodle_mobile.png - :align: center - :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/documentation/docs/images/lmssetup/moodle_mobile.png - -If you have a restrictive Moodle setup and troubles with the Moodle API account to use with SEB Server, please try to import the following -Moodle role profile within your Moodle instance. This profile will create a SEB Server role within Moodle that can be used to apply to an -API account to be used with SEB Server. The role defines only the necessary privileges and functions needed for SEB Server communication. - -Moodle role and account settings: :download:`XML ` - -.. note:: - If you want to use Moodle with SEB Server, we recomend to install the new Moodle Plugin for SEB Server for better integration with Moodle. - This plugin comes with the common SEB Server integration features and improved Moodle bining. For more information see :ref:`lms-setup-moodle-plugin-label` - - - -.. _lms-setup-rest-plugin-label: - -Install SEB restriction API plugin ----------------------------------- - -.. _lms-setup-edx-plugin-label: - -**Open edX SEB Plugin** - - There is a SEB integration plugin developed and supported by `eduNEXT `_. - - `Documentation `_ - - `Repository `_ - - -.. _lms-setup-moodle-plugin-label: - -**Moodle Plugin for SEB Server** - - There is a new SEB Server integration plugin for Moodle available since SEB Server 1.5 that can be used with the LMS Setup type Moodle with SEB Server Plugin. - This Plugin supports and improves all common SEB Server LMS binding features such as Course-Access, SEB Restriction and LMS Session Name Resolving. - It is also planed to extend and improve this plugin with new Moodle specific feature for further releases of SEB Server. - - `Documentation `_ - - `Repository `_ - +.. _lms-setup-label: + +Learning Management System Setup +================================ + +Overview +-------- + +To be able to connect to a learning management system (LMS), to view and manage the courses provided by a LMS is an essential feature of the SEB Server. +To setup an exam or e-assessment for SEB on SEB Server that is based on a course from a LMS, we have to make a binding to the course on the LMS. +This is also used to always get the actual course data from LMS like start- end-time, name and others. +Another feature of SEB Server that needs a LMS communication is the SEB restriction. A SEB restriction will restrict course access on the LMS only +for connection with Safe Exam Browser and will also check if a Safe Exam Browser of trust is used and the right configuration is used by the +Safe Exam Browser that was defines for the exam on the SEB Server. + +**Course API** + +This API, provided by the LMS, is used by the SEB Server to query the available courses and the needed data for each course. This API +is needed to be able to import a course from the LMS as an exam into SEB Server and configure the course as an e-assessment with SEB. +Usually this API comes as a REST or SOAP API with the core LMS implementation or a plugin. + +SEB Server supports this course API's so far: + - Open edX: The standard system `Open edX REST API `_. The SEB Server uses the "courses" endpoints to get course data. + - Moodle (Course Access): The standard system `Moodle REST API `_. The SEB Server uses the standard Moodle rest endpoints to get course data. + Please note that a second Moodle integration part for SEB access restriction with Config-Key will follow together with a Moodle plugin in a future version of SEB Server + + +**SEB Restriction API** + +If the automated SEB restriction functionality is available for a LMS depends on the following requirements: + +- There must exist a SEB integration plugin that offers an API to put and pull SEB restrictions in the form of Config-Keys and/or Browser-Exam-Keys + To the LMS and a specific course on the LMS to restrict the access. Such a plugin may also offer additional restriction features like restricting + on course section or course components or only for specified user roles. +- The SEB integration plugin must be installed on the LMS that is used by the SEB Server. + +For more information about known SEB integration plugins that are supported by the SEB Server see :ref:`lms-setup-rest-plugin-label` + +Regardless if a supported LMS is missing the SEB integration plugin installation, the LMS can be used with the Course API and an exam +setup will be possible but without automated SEB restriction feature. + +To be able to connect to an LMS from SEB Server, we need to create an API access account on the LMS side that can be used by the SEB Server to +access the API of the LMS. How to do this for the different supported types of LMS see :ref:`lms-api-account-label`. +After such an account was created, the account credentials, username and password, can be used by the SEB Server to connect to the LMS. +Therefore we need to create a LMS Setup on the SEB Server. + +.. image:: images/lmssetup/new.png + :align: center + :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/lmssetup/new.png + +A SEB Server administrator role will be able to see the institution to which the LMS Setup belongs to while an institutional administrator +is only able to see and create LMS Setup for its own institution. The name of the LMS Setup should be unique and is to identify a LMS +SEB Server internally. Use the **"Type"** selector to specify the type of the LMS to bind to the SEB Server within the LMS Setup. Currently supported are: + +- **Testing**: This is for testing purposes only and can be used to mock a LMS to test exam settings. This type provides some mock-up courses within the + LMS API of the SEB Server that can be seen in the LMS Exam Lookup once the LMS text setup is active. This mock-up courses can be imported and configured + as exams like they would exist. But note the a SEB client that is trying to connect to such a course would not be able to connect to the LMS since it + is not existing. But a SEB client is able to download the defined exam configuration for testing. +- **Open edX**: This type is to bind an existing `Open edX `_ LMS system that is available on the Internet or intranet. The SEB + Server tries to make use of the above described API's of the Open edX system. + + .. note:: + If you want to use the automated SEB restriction feature too, the `Open edX SEB Plugin `_ must be installed properly on the LMS. + +- **Moodle**: This type is to bind an existing `Moodle `_ LMS system that is available on the Internet or intranet. The SEB + Server tries to make use of the described API's of the Moodle system but there is currently no SEB restriction plugin available that works + with SEB Server. Note that Moodle integration is implemented partially within SEB Server version 1.1.x. Only the course access feature is implemented and the course restriction feature will come with a future SEB Server release + +- **Moodle with SEB Server Plugin**: The `SEB Server Plugin for Moodle `_ is new and supported by SEB Server since version 1.5. + With this plugin installed on Moodle side, SEB Server is able to more efficiently communicate with Moodle to fetch course data as well as restricting the quiz on Moodle side + For SEB only access, using a auto-generated Browser Exam Key (BEK) for SEB restriction. Also the Moodle user name resolving for SEB Server monitoring is less error prone especially + if Single Sign On some kind of login provider for Moodle is involved. Furthermore the new SEB Server Plugin for Moodle will be constantly extended and improved with new features in the future. + +- **Ans Delft**: This type is to bind SEB Server with an `Ans Delft `_ LMS. With the API credentials from an Ans Delft instance, SEB Server is able + to connect to the Ans LMS and provide the common features for Course-Access, SEB Restriction and LMS User Session resolving. + +- **Open Olat**: This type is to bind SEB Server with an `Open Olat `_ LMS. With the API credentials from an Open Olat instance, SEB Server is able + to connect to the Olat LMS and provide the common features for Course-Access, SEB Restriction and LMS User Session resolving. For more information please contact the Olat Development-Team at `OpenOLAT UZH `_ + +The **"LMS Server Address"** is the root URL to connect to the LMS server with HTTP over the Internet or intranet. This is usually the URL that is +also used with the Browser to connect to the main page of the LMS system. And additionally the credentials that have been created with the creation of the :ref:`lms-api-account-label` has to be set in the LMS Setup the make the SEB Server +able to securely connect to the LMS. The API credentials that consists of a client-name and a client-secret must be used with the **"LMS Server Username"** +and the **"LMS Server Password"** fields of the LMS Setup form on SEB Server. + +Alternatively to **"LMS Server Username"** and **"LMS Server Password"** you can use a direct **Access Token** to connect to the LMS API if the respective LMS allows to +generate and use an access token directly. + +If the SEB Server running behind a proxy server or a firewall between SEB Server den LMS, the additional proxy settings can be used to setup the proxy-connection. + +.. note:: + To Setup a Test LMS Setup (of type "Test") only a correct URL pattern must be set like "http://test" for example. And API credentials can be anything but must be set. + +After all the settings for a LMS Setup have been set, one can use either the "Save LMS Setup" action to save the LMS Setup without activation or the +"Activate LMS Setup" action to also activate the settings right after they has been successfully saved. Anyway, for both action there is an initial test +that, additionally to the usual field validation that takes place first, tries to connect to the LMS with the given API details. If the connection +wasn't successful, the SEB Server will inform the user about a possible reason of failure. Otherwise SEB Server shows a success message and the created +LMS Setup can be used. + +Use the "Activate / Deactivate LMS Setup" action to activate an inactive LMS Setup or the deactivate an active LMS Setup. + +.. note:: + On deactivation of an LMS Setup, the system checks on depending object and will show a confirmation to the user asking that all depending + objects will also been deactivated. Depending objects of an LMS Setup are exams that has been imported from the specified LMS Setup in the past. + + +Use Cases +--------- + +**Create a new LMS Setup for Open edX** + +A new Open edX system has been installed within your institution and to be able to use the system also for e-assessments with SEB and SEB Server, +you have to bind the LMS to the SEB Server. + +- If not already done, install the `Open edX SEB Plugin `_ on the Open edX system first. +- If you don't already have an API access account on Open edX side, `create one `_ +- Sign into SEB Server with your institutional administrator role account. +- Navigate to "Exam Administration" / "LMS Setup" within the navigation on the left hand side. +- Use the "Add LMS Setup" action from the right action pane to open a LMS Setup creation form. +- Give a unique name to the new LMS Setup for internally identification. +- Set the main URL that points to the new LMS system. This is usually the URL that is also used with the Browser to connect to the main page of the LMS system +- Set the API credentials that has been creates within step two (client-id, secret). +- Use the "Activate LMS Setup" action on the right action pane to test, save and activate the new LMS Setup within one step. + +.. note:: + If some form attributes are missing or not correct, the SEB Server system will respond with the usual form validation errors. + If the connection to the LMS is failing because of missing or wrong credentials or for any other reason the system is not able to connect to the LMS + the SEB Server will notify an error dialog to the user. + + +**Change API Credentials of an Active LMS Setup** + +The API access account on the LMS has been expired and you have to create a new one or update the old one which both result in new API access credentials +that has to be set on the existing LMS Setup on the SEB Server. + +.. image:: images/lmssetup/list.png + :align: center + :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/lmssetup/list.png + +- Sign into SEB Server with your institutional administrator role account. +- Navigate to "Exam Administration" / "LMS Setup" within the navigation on the left hand side. +- Use the Filter above the list to find the specified LMS Setup. +- Select the LMS Setup from the list and use the "Edit LMS Setup" action from the right action pane to open the LMS Setup in edit mode. +- Set the new credentials and make sure, the LMS Setup is still active. +- Use the "Save LMS Setup" action form the right action pane to save the changes and test the connection. + +.. note:: + If some form attributes are missing or not correct, the SEB Server system will respond with the usual form validation errors. + If the connection to the LMS is failing because of missing or wrong credentials or for any other reason the system is not able to connect to the LMS + the SEB Server will notify an error dialog to the user. + +**Deactivate LMS Setup** + +A LMS system that was running on your campus to provide e-assessment with SEB and SEB Server has been shut down and you need to also deactivate +the setup and exams on the SEB Server for this LMS. + +- Sign into SEB Server with your institutional administrator role account. +- Navigate to "Exam Administration" / "LMS Setup" within the navigation on the left hand side. +- Use the Filter above the list to find the specified LMS Setup. +- Select the specified LMS Setup from the list and use the "Deactivate LMS Setup" action from the right action pane. +- Alternatively you can also double-click on the LMS Setup to fist go into the detailed view of the LMS setup and use the "Deactivate LMS Setup" action there. +- The system informs you about the number of depending exams that also will be deactivated within the deactivation of the LMS Setup. +- Confirm the deactivation and notify that the LMS Setup now is listed as "Inactive" in the list. +- Navigate to "LMS Exam Lookup" to make sure the courses form the deactivated LMS Setup are not available anymore. +- Navigate also to "Exam" and make sure that all previously imported exams from the deactivated LMS Setup are not available anymore. + +.. _lms-api-account-label: + +API Access Account on LMS +-------------------------- + +.. _lms-api-account-edx-label: + +**Create Open edX API Access Account** + +To be able to create an API access-account on Open edX you need a user-account with staff and administration privileges. + +**For Open edX Hawthorn and Ironwood versions following the steps below::** + +- Login to Open edX LMS Administration with an appropriate user-account that has administration rights. And find the Users section: + +.. image:: images/lmssetup/openEdxAPIAccess1.bmp + :align: center + :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/lmssetup/openEdxAPIAccess1.bmp + +- Create a new User-Account that acts as an API account. The account must at least have the permissions to query the course API of Open edX and to access the seb_openedx plugin permission. +- Make sure that "Staff" status is checked for the account. + +.. image:: images/lmssetup/openEdxAPIAccess2.bmp + :align: center + :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/lmssetup/openEdxAPIAccess2.bmp + +- Back in the administration homepage, find the OAUT2 - Client section and create a new API Client Access for the given User-Account. The Client id and Client secret are automatically generated by Open edx. + +.. image:: images/lmssetup/openEdxAPIAccess3.bmp + :align: center + :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/lmssetup/openEdxAPIAccess3.bmp + +.. image:: images/lmssetup/openEdxAPIAccess4.bmp + :align: center + :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/master/docs/images/lmssetup/openEdxAPIAccess4.bmp + +Once the client registration was successful the client id and client secret can be used within the SEB Server to access the course- and SEB-restriction API of Open edX as described in the next step section + +.. note:: + Since Open edX Juniper is using Django Oauth Toolkit instead of Django Oauth Provider the last step in the above guide looks slightly different. Please see below the last step for setting up on an Open edX Juniper version. + +- Back in the administration homepage, find the DJANGO OAUTH TOOLKIT - Applications section and create a new API Application Access for the given User-Account. The Client id can be defined and the Client secret is automatically be generated by Open edx. + +.. image:: images/lmssetup/openEdxAPIAccess5.png + :align: center + :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/documentation/docs/images/lmssetup/openEdxAPIAccess5.png + +.. image:: images/lmssetup/openEdxAPIAccess6.png + :align: center + :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/documentation/docs/images/lmssetup/openEdxAPIAccess6.png + + + +**Create Moodle API Access Account** + +To be able to create an LMS Setup for Moodle you need a Moodle administrator or manager account. You can then use this account in the LMS Setup to connect to the LMS. + +Since SEB Server uses some functions from the Moodle's mobile API, you have to make sure the web services for mobile apps are enabled within your Moodle setup. +To do so please login to Moodle with an administrator account and go to "Side Administration", scroll down to "Mobile App" and choose "Mobile Settings. + +.. image:: images/lmssetup/moodle_mobile.png + :align: center + :target: https://raw.githubusercontent.com/SafeExamBrowser/seb-server/documentation/docs/images/lmssetup/moodle_mobile.png + +If you have a restrictive Moodle setup and troubles with the Moodle API account to use with SEB Server, please try to import the following +Moodle role profile within your Moodle instance. This profile will create a SEB Server role within Moodle that can be used to apply to an +API account to be used with SEB Server. The role defines only the necessary privileges and functions needed for SEB Server communication. + +Moodle role and account settings: :download:`XML ` + +.. note:: + If you want to use Moodle with SEB Server, we recomend to install the new Moodle Plugin for SEB Server for better integration with Moodle. + This plugin comes with the common SEB Server integration features and improved Moodle bining. For more information see :ref:`lms-setup-moodle-plugin-label` + + + +.. _lms-setup-rest-plugin-label: + +Install SEB restriction API plugin +---------------------------------- + +.. _lms-setup-edx-plugin-label: + +**Open edX SEB Plugin** + + There is a SEB integration plugin developed and supported by `eduNEXT `_. + - `Documentation `_ + - `Repository `_ + + +.. _lms-setup-moodle-plugin-label: + +**Moodle Plugin for SEB Server** + + There is a new SEB Server integration plugin for Moodle available since SEB Server 1.5 that can be used with the LMS Setup type Moodle with SEB Server Plugin. + This Plugin supports and improves all common SEB Server LMS binding features such as Course-Access, SEB Restriction and LMS Session Name Resolving. + It is also planed to extend and improve this plugin with new Moodle specific feature for further releases of SEB Server. + - `Documentation `_ + - `Repository `_ + From ea35b7c0e45cb4d032fae1ea3992d0ef37f74049 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luca=20B=C3=B6sch?= Date: Mon, 15 May 2023 16:17:28 +0200 Subject: [PATCH 04/31] Documentation improvements. --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 87b3fcfe..c843877a 100644 --- a/README.rst +++ b/README.rst @@ -32,7 +32,7 @@ What is Safe Exam Browser Server (SEB Server)? While the interaction with SEB is well known in Learning Management Systems (LMS) like `Open edX `_, `Moodle `_ etc. the SEB Server is an entirely new component to set up secured online exams. -It interacts with the assessments system/LMS as well as with SEB on exam clients.It supports exam scenarios on student owned devices (BYOD) +It interacts with the assessments system/LMS as well as with SEB on exam clients. It supports exam scenarios on student owned devices (BYOD) and on managed devices. SEB Server is a modern webservice with a REST API and a GUI service on top of it. SEB Server is written in Java and uses Docker for installation and setup. @@ -106,7 +106,7 @@ SEB - SEB Server Compatibility ------------------------------ The table below shows available and upcoming SEB client versions that has SEB Server integration support and are compatible with particular -SEB Server version. There is an entry for each platform with a beta or testing release date and a official release date. +SEB Server versions. There is an entry for each platform with a beta or testing release date and an official release date. **SEB Server Version 1.5.X** From 9c27e6ca606fb9a53af2d88c716bb6efebaf11a9 Mon Sep 17 00:00:00 2001 From: anhefti Date: Mon, 19 Jun 2023 14:44:55 +0200 Subject: [PATCH 05/31] fixed README --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 1087fb53..13cb3d92 100644 --- a/README.rst +++ b/README.rst @@ -99,12 +99,12 @@ Bugfixes: Docker-Image: - Exact release version: docker pull anhefti/seb-server:v1.5.0 (sha256:21d62e24dd5cf697ab5f2b437dc458e6c7492ea294f77a424d39d05164d6c8cc) -- Latest stable minor version with patches: docker pull anhefti/seb-server:v1.5-stable +- Stable minor version: docker pull anhefti/seb-server:v1.5-stable Latest Version is 1.5.1 with Docker-Image: - Exact release version: docker pull anhefti/seb-server:v1.5.1 (sha256:a866faa18848d15301e9f06d17aab1c7293d2a27d967038d32410f817e478408) -- Latest stable minor version with patches: docker pull anhefti/seb-server:v1.5-latest +- Latest stable minor version with latest patches: docker pull anhefti/seb-server:v1.5-latest SEB - SEB Server Compatibility From 00995bee961fded71f903596baca243ec4426e58 Mon Sep 17 00:00:00 2001 From: anhefti Date: Mon, 19 Jun 2023 16:35:22 +0200 Subject: [PATCH 06/31] Merge remote-tracking branch 'origin/rel-1.5.1' into dev-1.5 --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 13cb3d92..1213649d 100644 --- a/README.rst +++ b/README.rst @@ -103,7 +103,7 @@ Docker-Image: Latest Version is 1.5.1 with Docker-Image: -- Exact release version: docker pull anhefti/seb-server:v1.5.1 (sha256:a866faa18848d15301e9f06d17aab1c7293d2a27d967038d32410f817e478408) +- Exact release version: docker pull anhefti/seb-server:v1.5.1 (sha256:af860f5dd4d99db3e7acaa66d26c3ee72cf0ad08d8ca88febec6d4ecd160b9cf) - Latest stable minor version with latest patches: docker pull anhefti/seb-server:v1.5-latest From 429b3939490835acd038d5aeec0931ea494dcfef Mon Sep 17 00:00:00 2001 From: anhefti Date: Tue, 3 Oct 2023 11:57:54 +0200 Subject: [PATCH 07/31] added quizaccess/sebserver:managesebserver to moodle privileges --- docs/files/webservice_seb-server.xml | 737 ++++++++++++++++++++++++++- 1 file changed, 736 insertions(+), 1 deletion(-) diff --git a/docs/files/webservice_seb-server.xml b/docs/files/webservice_seb-server.xml index 7c723a2d..a01f32de 100644 --- a/docs/files/webservice_seb-server.xml +++ b/docs/files/webservice_seb-server.xml @@ -1,2 +1,737 @@ -webservice_seb-serverwebservice_SEB-Serversystematto/h5p:addembedatto/recordrtc:recordaudioatto/recordrtc:recordvideoauth/oauth2:managelinkedloginsblock/activity_modules:addinstanceblock/activity_results:addinstanceblock/admin_bookmarks:addinstanceblock/admin_bookmarks:myaddinstanceblock/badges:addinstanceblock/badges:myaddinstanceblock/blog_menu:addinstanceblock/blog_recent:addinstanceblock/blog_tags:addinstanceblock/calendar_month:addinstanceblock/calendar_month:myaddinstanceblock/calendar_upcoming:addinstanceblock/calendar_upcoming:myaddinstanceblock/comments:addinstanceblock/comments:myaddinstanceblock/completionstatus:addinstanceblock/course_list:addinstanceblock/course_list:myaddinstanceblock/course_summary:addinstanceblock/feedback:addinstanceblock/globalsearch:addinstanceblock/globalsearch:myaddinstanceblock/glossary_random:addinstanceblock/glossary_random:myaddinstanceblock/html:addinstanceblock/html:myaddinstanceblock/login:addinstanceblock/lp:addinstanceblock/lp:myaddinstanceblock/mentees:addinstanceblock/mentees:myaddinstanceblock/mnet_hosts:addinstanceblock/mnet_hosts:myaddinstanceblock/myoverview:myaddinstanceblock/myprofile:addinstanceblock/myprofile:myaddinstanceblock/navigation:addinstanceblock/navigation:myaddinstanceblock/news_items:addinstanceblock/news_items:myaddinstanceblock/onlinesurvey:addinstanceblock/onlinesurvey:myaddinstanceblock/onlinesurvey:viewblock/onlinesurvey:view_debugdetailsblock/online_users:addinstanceblock/online_users:myaddinstanceblock/online_users:viewlistblock/opencast:addinstanceblock/opencast:addltiblock/opencast:addltiepisodeblock/opencast:addvideoblock/opencast:createseriesforcourseblock/opencast:defineseriesforcourseblock/opencast:deleteeventblock/opencast:myaddinstanceblock/opencast:unassigneventblock/opencast:viewunpublishedvideosblock/private_files:addinstanceblock/private_files:myaddinstanceblock/quiz_results:addinstanceblock/recent_activity:addinstanceblock/recent_activity:viewaddupdatemoduleblock/recent_activity:viewdeletemoduleblock/recentlyaccessedcourses:myaddinstanceblock/recentlyaccesseditems:myaddinstanceblock/rss_client:addinstanceblock/rss_client:manageanyfeedsblock/rss_client:manageownfeedsblock/rss_client:myaddinstanceblock/search_forums:addinstanceblock/section_links:addinstanceblock/selfcompletion:addinstanceblock/settings:addinstanceblock/settings:myaddinstanceblock/site_main_menu:addinstanceblock/social_activities:addinstanceblock/starredcourses:myaddinstanceblock/tag_flickr:addinstanceblock/tags:addinstanceblock/tags:myaddinstanceblock/tag_youtube:addinstanceblock/timeline:myaddinstancebooktool/exportimscp:exportbooktool/importhtml:importbooktool/print:printcontenttype/h5p:accesscontenttype/h5p:uploadcontenttype/h5p:useeditorenrol/category:configenrol/category:synchronisedenrol/cohort:configenrol/cohort:unenrolenrol/database:configenrol/database:unenrolenrol/flatfile:manageenrol/flatfile:unenrolenrol/guest:configenrol/imsenterprise:configenrol/ldap:manageenrol/lti:configenrol/lti:unenrolenrol/manual:configenrol/manual:enrolenrol/manual:manageenrol/manual:unenrolenrol/manual:unenrolselfenrol/meta:configenrol/meta:selectaslinkedenrol/meta:unenrolenrol/mnet:configenrol/paypal:configenrol/paypal:manageenrol/paypal:unenrolenrol/paypal:unenrolselfenrol/self:configenrol/self:holdkeyenrol/self:manageenrol/self:unenrolenrol/self:unenrolselfformat/columns:changecolumnsformat/grid:changeimagecontainersizeformat/grid:changeimagecontainerstyleformat/grid:changeimageresizemethodformat/topcoll:changecolourformat/topcoll:changelayoutformat/topcoll:changetogglealignmentformat/topcoll:changetoggleiconsetforumreport/summary:viewforumreport/summary:viewallgradeexport/ods:publishgradeexport/ods:viewgradeexport/txt:publishgradeexport/txt:viewgradeexport/xls:publishgradeexport/xls:viewgradeexport/xml:publishgradeexport/xml:viewgradeimport/csv:viewgradeimport/direct:viewgradeimport/xml:publishgradeimport/xml:viewgradereport/grader:viewgradereport/history:viewgradereport/outcomes:viewgradereport/overview:viewgradereport/singleview:viewgradereport/user:viewmessage/airnotifier:managedevicemod/assign:addinstancemod/assign:editothersubmissionmod/assign:exportownsubmissionmod/assign:grademod/assign:grantextensionmod/assign:manageallocationsmod/assign:managegradesmod/assign:manageoverridesmod/assignment:addinstancemod/assignment:exportownsubmissionmod/assignment:grademod/assignment:submitmod/assignment:viewmod/assign:receivegradernotificationsmod/assign:releasegradesmod/assign:revealidentitiesmod/assign:reviewgradesmod/assign:showhiddengradermod/assign:submitmod/assign:viewmod/assign:viewblinddetailsmod/assign:viewgradesmod/book:addinstancemod/book:editmod/book:readmod/book:viewhiddenchaptersmod/chat:addinstancemod/chat:chatmod/chat:deletelogmod/chat:exportparticipatedsessionmod/chat:exportsessionmod/chat:readlogmod/chat:viewmod/choice:addinstancemod/choice:choosemod/choice:deleteresponsesmod/choice:downloadresponsesmod/choice:readresponsesmod/choice:viewmod/data:addinstancemod/data:approvemod/data:commentmod/data:exportallentriesmod/data:exportentrymod/data:exportownentrymod/data:exportuserinfomod/data:managecommentsmod/data:manageentriesmod/data:managetemplatesmod/data:manageuserpresetsmod/data:ratemod/data:viewmod/data:viewallratingsmod/data:viewalluserpresetsmod/data:viewanyratingmod/data:viewentrymod/data:viewratingmod/data:writeentrymod/feedback:addinstancemod/feedback:completemod/feedback:createprivatetemplatemod/feedback:createpublictemplatemod/feedback:deletesubmissionsmod/feedback:deletetemplatemod/feedback:edititemsmod/feedback:mapcoursemod/feedback:receivemailmod/feedback:viewmod/feedback:viewanalysepagemod/feedback:viewreportsmod/folder:addinstancemod/folder:managefilesmod/folder:viewmod/forum:addinstancemod/forum:addnewsmod/forum:addquestionmod/forum:allowforcesubscribemod/forum:canoverridecutoffmod/forum:canoverridediscussionlockmod/forum:canposttomygroupsmod/forum:cantogglefavouritemod/forum:createattachmentmod/forum:deleteanypostmod/forum:deleteownpostmod/forum:editanypostmod/forum:exportdiscussionmod/forum:exportforummod/forum:exportownpostmod/forum:exportpostmod/forum:grademod/forum:managesubscriptionsmod/forum:movediscussionsmod/forum:pindiscussionsmod/forum:postprivatereplymod/forum:postwithoutthrottlingmod/forum:ratemod/forum:readprivaterepliesmod/forum:replynewsmod/forum:replypostmod/forum:splitdiscussionsmod/forum:startdiscussionmod/forum:viewallratingsmod/forum:viewanyratingmod/forum:viewdiscussionmod/forum:viewhiddentimedpostsmod/forum:viewqandawithoutpostingmod/forum:viewratingmod/forum:viewsubscribersmod/glossary:addinstancemod/glossary:approvemod/glossary:commentmod/glossary:exportmod/glossary:exportentrymod/glossary:exportownentrymod/glossary:importmod/glossary:managecategoriesmod/glossary:managecommentsmod/glossary:manageentriesmod/glossary:ratemod/glossary:viewmod/glossary:viewallratingsmod/glossary:viewanyratingmod/glossary:viewratingmod/glossary:writemod/h5pactivity:addinstancemod/h5pactivity:reviewattemptsmod/h5pactivity:submitmod/h5pactivity:viewmod/imscp:addinstancemod/imscp:viewmod/label:addinstancemod/label:viewmod/lesson:addinstancemod/lesson:editmod/lesson:grademod/lesson:managemod/lesson:manageoverridesmod/lesson:viewmod/lesson:viewreportsmod/lti:addcoursetoolmod/lti:addinstancemod/lti:addmanualinstancemod/lti:addpreconfiguredinstancemod/lti:adminmod/lti:managemod/lti:requesttooladdmod/lti:viewmod/page:addinstancemod/page:viewmod/quiz:addinstancemod/quiz:attemptmod/quiz:deleteattemptsmod/quiz:emailconfirmsubmissionmod/quiz:emailnotifysubmissionmod/quiz:emailwarnoverduemod/quiz:grademod/quiz:ignoretimelimitsmod/quiz:managemod/quiz:manageoverridesmod/quiz:previewmod/quiz:regrademod/quiz:reviewmyattemptsmod/resource:addinstancemod/resource:viewmod/scorm:addinstancemod/scorm:deleteownresponsesmod/scorm:deleteresponsesmod/scorm:savetrackmod/scorm:skipviewmod/scorm:viewreportmod/scorm:viewscoresmod/survey:addinstancemod/survey:downloadmod/survey:participatemod/survey:readresponsesmod/url:addinstancemod/url:viewmod/wiki:addinstancemod/wiki:createpagemod/wiki:editcommentmod/wiki:editpagemod/wiki:managecommentmod/wiki:managefilesmod/wiki:managewikimod/wiki:overridelockmod/wiki:viewcommentmod/wiki:viewpagemod/workshop:addinstancemod/workshop:allocatemod/workshop:deletesubmissionsmod/workshop:editdimensionsmod/workshop:exportsubmissionsmod/workshop:ignoredeadlinesmod/workshop:manageexamplesmod/workshop:overridegradesmod/workshop:peerassessmod/workshop:publishsubmissionsmod/workshop:submitmod/workshop:switchphasemod/workshop:viewmod/workshop:viewallassessmentsmod/workshop:viewallsubmissionsmod/workshop:viewauthornamesmod/workshop:viewauthorpublishedmod/workshop:viewpublishedsubmissionsmod/workshop:viewreviewernamesmoodle/analytics:listinsightsmoodle/analytics:listowninsightsmoodle/analytics:managemodelsmoodle/backup:anonymisemoodle/backup:backupactivitymoodle/backup:backupcoursemoodle/backup:backupsectionmoodle/backup:backuptargetimportmoodle/backup:configuremoodle/backup:downloadfilemoodle/backup:userinfomoodle/badges:awardbadgemoodle/badges:configurecriteriamoodle/badges:configuredetailsmoodle/badges:configuremessagesmoodle/badges:createbadgemoodle/badges:deletebadgemoodle/badges:earnbadgemoodle/badges:manageglobalsettingsmoodle/badges:manageownbadgesmoodle/badges:revokebadgemoodle/badges:viewawardedmoodle/badges:viewbadgesmoodle/badges:viewotherbadgesmoodle/block:editmoodle/block:viewmoodle/blog:createmoodle/blog:manageentriesmoodle/blog:manageexternalmoodle/blog:searchmoodle/blog:viewmoodle/blog:viewdraftsmoodle/calendar:manageentriesmoodle/calendar:managegroupentriesmoodle/calendar:manageownentriesmoodle/category:managemoodle/cohort:assignmoodle/cohort:managemoodle/cohort:viewmoodle/comment:deletemoodle/comment:postmoodle/comment:viewmoodle/competency:competencygrademoodle/competency:competencymanagemoodle/competency:competencyviewmoodle/competency:coursecompetencyconfiguremoodle/competency:coursecompetencygradablemoodle/competency:coursecompetencymanagemoodle/competency:coursecompetencyviewmoodle/competency:evidencedeletemoodle/competency:plancommentmoodle/competency:plancommentownmoodle/competency:planmanagemoodle/competency:planmanagedraftmoodle/competency:planmanageownmoodle/competency:planmanageowndraftmoodle/competency:planrequestreviewmoodle/competency:planrequestreviewownmoodle/competency:planreviewmoodle/competency:planviewmoodle/competency:planviewdraftmoodle/competency:planviewownmoodle/competency:planviewowndraftmoodle/competency:templatemanagemoodle/competency:templateviewmoodle/competency:usercompetencycommentmoodle/competency:usercompetencycommentownmoodle/competency:usercompetencyrequestreviewmoodle/competency:usercompetencyrequestreviewownmoodle/competency:usercompetencyreviewmoodle/competency:usercompetencyviewmoodle/competency:userevidencemanagemoodle/competency:userevidencemanageownmoodle/competency:userevidenceviewmoodle/contentbank:accessmoodle/contentbank:deleteanycontentmoodle/contentbank:deleteowncontentmoodle/contentbank:manageanycontentmoodle/contentbank:manageowncontentmoodle/contentbank:uploadmoodle/contentbank:useeditormoodle/course:activityvisibilitymoodle/course:bulkmessagingmoodle/course:changecategorymoodle/course:changefullnamemoodle/course:changeidnumbermoodle/course:changelockedcustomfieldsmoodle/course:changeshortnamemoodle/course:changesummarymoodle/course:configurecustomfieldsmoodle/course:createmoodle/course:creategroupconversationsmoodle/course:deletemoodle/course:enrolconfigmoodle/course:enrolreviewmoodle/course:ignoreavailabilityrestrictionsmoodle/course:ignorefilesizelimitsmoodle/course:isincompletionreportsmoodle/course:manageactivitiesmoodle/course:managefilesmoodle/course:managegroupsmoodle/course:managescalesmoodle/course:markcompletemoodle/course:movesectionsmoodle/course:overridecompletionmoodle/course:recommendactivitymoodle/course:renamerolesmoodle/course:requestmoodle/course:resetmoodle/course:reviewotherusersmoodle/course:sectionvisibilitymoodle/course:setcurrentsectionmoodle/course:setforcedlanguagemoodle/course:tagmoodle/course:togglecompletionmoodle/course:updatemoodle/course:useremailmoodle/course:viewhiddenactivitiesmoodle/course:viewscalesmoodle/course:viewsuspendedusersmoodle/course:visibilitymoodle/filter:managemoodle/grade:editmoodle/grade:exportmoodle/grade:hidemoodle/grade:importmoodle/grade:lockmoodle/grade:managemoodle/grade:managegradingformsmoodle/grade:managelettersmoodle/grade:manageoutcomesmoodle/grade:managesharedformsmoodle/grade:sharegradingformsmoodle/grade:unlockmoodle/grade:viewmoodle/grade:viewallmoodle/grade:viewhiddenmoodle/h5p:deploymoodle/h5p:setdisplayoptionsmoodle/h5p:updatelibrariesmoodle/my:configsyspagesmoodle/my:manageblocksmoodle/notes:managemoodle/notes:viewmoodle/portfolio:exportmoodle/question:addmoodle/question:configmoodle/question:editallmoodle/question:editminemoodle/question:flagmoodle/question:managecategorymoodle/question:moveallmoodle/question:moveminemoodle/question:tagallmoodle/question:tagminemoodle/question:useallmoodle/question:useminemoodle/question:viewallmoodle/question:viewminemoodle/rating:ratemoodle/rating:viewmoodle/rating:viewallmoodle/rating:viewanymoodle/restore:configuremoodle/restore:createusermoodle/restore:restoreactivitymoodle/restore:restorecoursemoodle/restore:restoresectionmoodle/restore:restoretargetimportmoodle/restore:rolldatesmoodle/restore:uploadfilemoodle/restore:userinfomoodle/restore:viewautomatedfileareamoodle/role:assignmoodle/role:managemoodle/role:overridemoodle/role:reviewmoodle/role:safeoverridemoodle/role:switchrolesmoodle/search:querymoodle/site:approvecoursemoodle/site:configmoodle/site:configviewmoodle/site:deleteanymessagemoodle/site:deleteownmessagemoodle/site:doclinksmoodle/site:forcelanguagemoodle/site:maintenanceaccessmoodle/site:manageallmessagingmoodle/site:manageblocksmoodle/site:managecontextlocksmoodle/site:messageanyusermoodle/site:mnetlogintoremotemoodle/site:readallmessagesmoodle/site:sendmessagemoodle/site:trustcontentmoodle/site:uploadusersmoodle/site:viewanonymouseventsmoodle/site:viewfullnamesmoodle/site:viewparticipantsmoodle/site:viewreportsmoodle/site:viewuseridentitymoodle/tag:editmoodle/tag:editblocksmoodle/tag:flagmoodle/tag:managemoodle/user:changeownpasswordmoodle/user:createmoodle/user:deletemoodle/user:editmessageprofilemoodle/user:editownmessageprofilemoodle/user:editownprofilemoodle/user:editprofilemoodle/user:ignoreuserquotamoodle/user:loginasmoodle/user:manageblocksmoodle/user:manageownblocksmoodle/user:manageownfilesmoodle/user:managesyspagesmoodle/user:readuserblogsmoodle/user:readuserpostsmoodle/user:updatemoodle/user:viewalldetailsmoodle/user:viewlastipmoodle/user:viewuseractivitiesreportmoodle/webservice:managealltokensqtype/lti:addcoursetoolqtype/lti:adddefaultinstanceqtype/lti:addgloballypreconfigedtoolinstanceqtype/lti:addinstanceqtype/lti:adminqtype/lti:backupcourseqtype/lti:manageqtype/lti:regradeltiqtype/lti:requesttooladdqtype/lti:viewquizaccess/seb:manage_filemanager_sebconfigfilequizaccess/seb:manage_seb_activateurlfilteringquizaccess/seb:manage_seb_allowedbrowserexamkeysquizaccess/seb:manage_seb_allowreloadinexamquizaccess/seb:manage_seb_allowspellcheckingquizaccess/seb:manage_seb_allowuserquitsebquizaccess/seb:manage_seb_enableaudiocontrolquizaccess/seb:manage_seb_expressionsallowedquizaccess/seb:manage_seb_expressionsblockedquizaccess/seb:manage_seb_filterembeddedcontentquizaccess/seb:manage_seb_linkquitsebquizaccess/seb:manage_seb_muteonstartupquizaccess/seb:manage_seb_quitpasswordquizaccess/seb:manage_seb_regexallowedquizaccess/seb:manage_seb_regexblockedquizaccess/seb:manage_seb_requiresafeexambrowserquizaccess/seb:manage_seb_showkeyboardlayoutquizaccess/seb:manage_seb_showreloadbuttonquizaccess/seb:manage_seb_showsebdownloadlinkquizaccess/seb:manage_seb_showsebtaskbarquizaccess/seb:manage_seb_showtimequizaccess/seb:manage_seb_showwificontrolquizaccess/seb:manage_seb_templateidquizaccess/seb:manage_seb_userconfirmquitquizaccess/seb:managetemplatesquizaccess/wifiresilience:adminmessagesquizaccess/wifiresilience:browserchecksquizaccess/wifiresilience:inspectresponsesquizaccess/wifiresilience:localresponsesquizaccess/wifiresilience:uploadresponsesquizaccess/wifiresilience:viewlivedevicesquizaccess/wifiresilience:viewtechchecksquiz/grading:viewidnumberquiz/grading:viewstudentnamesquiz/statistics:viewreport/completion:viewreport/customsql:definequeriesreport/customsql:managecategoriesreport/customsql:viewreport/loglive:viewreport/log:viewreport/log:viewtodayreport/outline:viewreport/outline:viewuserreportreport/participation:viewreport/performance:viewreport/progress:viewreport/questioninstances:viewreport/security:viewreport/stats:viewreport/status:viewreport/usersessions:manageownsessionsrepository/areafiles:viewrepository/boxnet:viewrepository/contentbank:accesscoursecategorycontentrepository/contentbank:accesscoursecontentrepository/contentbank:accessgeneralcontentrepository/contentbank:viewrepository/coursefiles:viewrepository/dropbox:viewrepository/equella:viewrepository/filesystem:viewrepository/flickr_public:viewrepository/flickr:viewrepository/googledocs:viewrepository/local:viewrepository/merlot:viewrepository/nextcloud:viewrepository/onedrive:viewrepository/opencast:viewrepository/picasa:viewrepository/recent:viewrepository/s3:viewrepository/skydrive:viewrepository/upload:viewrepository/url:viewrepository/user:viewrepository/webdav:viewrepository/wikimedia:viewrepository/youtube:viewtool/coursedates:setdatestool/customlang:edittool/customlang:viewtool/dataprivacy:downloadallrequeststool/dataprivacy:downloadownrequesttool/dataprivacy:makedatadeletionrequestsforchildrentool/dataprivacy:makedatarequestsforchildrentool/dataprivacy:managedataregistrytool/dataprivacy:managedatarequeststool/dataprivacy:requestdeletetool/dataprivacy:requestdeleteforotherusertool/lpmigrate:frameworksmigratetool/monitor:managerulestool/monitor:managetooltool/monitor:subscribetool/opencast:externalapitool/opencast:instructortool/opencast:learnertool/policy:accepttool/policy:acceptbehalftool/policy:managedocstool/policy:viewacceptancestool/recyclebin:deleteitemstool/recyclebin:restoreitemstool/recyclebin:viewitemstool/uploaduser:uploaduserpicturestool/usertours:managetourswebservice/soap:usewebservice/xmlrpc:usemod/quiz:viewmod/quiz:viewreportsmoodle/category:viewcourselistmoodle/category:viewhiddencategoriesmoodle/course:viewmoodle/course:viewhiddencoursesmoodle/course:viewhiddensectionsmoodle/course:viewhiddenuserfieldsmoodle/course:viewparticipantsmoodle/site:accessallgroupsmoodle/user:viewdetailsmoodle/user:viewhiddendetailsmoodle/webservice:createmobiletokenmoodle/webservice:createtokenquizaccess/seb:bypasssebreport/courseoverview:viewwebservice/rest:use + + webservice_seb-server + webservice_SEB-Server + + + + system + + + + + + + atto/h5p:addembed + atto/recordrtc:recordaudio + atto/recordrtc:recordvideo + auth/oauth2:managelinkedlogins + block/activity_modules:addinstance + block/activity_results:addinstance + block/admin_bookmarks:addinstance + block/admin_bookmarks:myaddinstance + block/badges:addinstance + block/badges:myaddinstance + block/blog_menu:addinstance + block/blog_recent:addinstance + block/blog_tags:addinstance + block/calendar_month:addinstance + block/calendar_month:myaddinstance + block/calendar_upcoming:addinstance + block/calendar_upcoming:myaddinstance + block/comments:addinstance + block/comments:myaddinstance + block/completionstatus:addinstance + block/course_list:addinstance + block/course_list:myaddinstance + block/course_summary:addinstance + block/feedback:addinstance + block/globalsearch:addinstance + block/globalsearch:myaddinstance + block/glossary_random:addinstance + block/glossary_random:myaddinstance + block/html:addinstance + block/html:myaddinstance + block/login:addinstance + block/lp:addinstance + block/lp:myaddinstance + block/mentees:addinstance + block/mentees:myaddinstance + block/mnet_hosts:addinstance + block/mnet_hosts:myaddinstance + block/myoverview:myaddinstance + block/myprofile:addinstance + block/myprofile:myaddinstance + block/navigation:addinstance + block/navigation:myaddinstance + block/news_items:addinstance + block/news_items:myaddinstance + block/onlinesurvey:addinstance + block/onlinesurvey:myaddinstance + block/onlinesurvey:view + block/onlinesurvey:view_debugdetails + block/online_users:addinstance + block/online_users:myaddinstance + block/online_users:viewlist + block/opencast:addinstance + block/opencast:addlti + block/opencast:addltiepisode + block/opencast:addvideo + block/opencast:createseriesforcourse + block/opencast:defineseriesforcourse + block/opencast:deleteevent + block/opencast:myaddinstance + block/opencast:unassignevent + block/opencast:viewunpublishedvideos + block/private_files:addinstance + block/private_files:myaddinstance + block/quiz_results:addinstance + block/recent_activity:addinstance + block/recent_activity:viewaddupdatemodule + block/recent_activity:viewdeletemodule + block/recentlyaccessedcourses:myaddinstance + block/recentlyaccesseditems:myaddinstance + block/rss_client:addinstance + block/rss_client:manageanyfeeds + block/rss_client:manageownfeeds + block/rss_client:myaddinstance + block/search_forums:addinstance + block/section_links:addinstance + block/selfcompletion:addinstance + block/settings:addinstance + block/settings:myaddinstance + block/site_main_menu:addinstance + block/social_activities:addinstance + block/starredcourses:myaddinstance + block/tag_flickr:addinstance + block/tags:addinstance + block/tags:myaddinstance + block/tag_youtube:addinstance + block/timeline:myaddinstance + booktool/exportimscp:export + booktool/importhtml:import + booktool/print:print + contenttype/h5p:access + contenttype/h5p:upload + contenttype/h5p:useeditor + enrol/category:config + enrol/category:synchronised + enrol/cohort:config + enrol/cohort:unenrol + enrol/database:config + enrol/database:unenrol + enrol/flatfile:manage + enrol/flatfile:unenrol + enrol/guest:config + enrol/imsenterprise:config + enrol/ldap:manage + enrol/lti:config + enrol/lti:unenrol + enrol/manual:config + enrol/manual:enrol + enrol/manual:manage + enrol/manual:unenrol + enrol/manual:unenrolself + enrol/meta:config + enrol/meta:selectaslinked + enrol/meta:unenrol + enrol/mnet:config + enrol/paypal:config + enrol/paypal:manage + enrol/paypal:unenrol + enrol/paypal:unenrolself + enrol/self:config + enrol/self:holdkey + enrol/self:manage + enrol/self:unenrol + enrol/self:unenrolself + format/columns:changecolumns + format/grid:changeimagecontainersize + format/grid:changeimagecontainerstyle + format/grid:changeimageresizemethod + format/topcoll:changecolour + format/topcoll:changelayout + format/topcoll:changetogglealignment + format/topcoll:changetoggleiconset + forumreport/summary:view + forumreport/summary:viewall + gradeexport/ods:publish + gradeexport/ods:view + gradeexport/txt:publish + gradeexport/txt:view + gradeexport/xls:publish + gradeexport/xls:view + gradeexport/xml:publish + gradeexport/xml:view + gradeimport/csv:view + gradeimport/direct:view + gradeimport/xml:publish + gradeimport/xml:view + gradereport/grader:view + gradereport/history:view + gradereport/outcomes:view + gradereport/overview:view + gradereport/singleview:view + gradereport/user:view + message/airnotifier:managedevice + mod/assign:addinstance + mod/assign:editothersubmission + mod/assign:exportownsubmission + mod/assign:grade + mod/assign:grantextension + mod/assign:manageallocations + mod/assign:managegrades + mod/assign:manageoverrides + mod/assignment:addinstance + mod/assignment:exportownsubmission + mod/assignment:grade + mod/assignment:submit + mod/assignment:view + mod/assign:receivegradernotifications + mod/assign:releasegrades + mod/assign:revealidentities + mod/assign:reviewgrades + mod/assign:showhiddengrader + mod/assign:submit + mod/assign:view + mod/assign:viewblinddetails + mod/assign:viewgrades + mod/book:addinstance + mod/book:edit + mod/book:read + mod/book:viewhiddenchapters + mod/chat:addinstance + mod/chat:chat + mod/chat:deletelog + mod/chat:exportparticipatedsession + mod/chat:exportsession + mod/chat:readlog + mod/chat:view + mod/choice:addinstance + mod/choice:choose + mod/choice:deleteresponses + mod/choice:downloadresponses + mod/choice:readresponses + mod/choice:view + mod/data:addinstance + mod/data:approve + mod/data:comment + mod/data:exportallentries + mod/data:exportentry + mod/data:exportownentry + mod/data:exportuserinfo + mod/data:managecomments + mod/data:manageentries + mod/data:managetemplates + mod/data:manageuserpresets + mod/data:rate + mod/data:view + mod/data:viewallratings + mod/data:viewalluserpresets + mod/data:viewanyrating + mod/data:viewentry + mod/data:viewrating + mod/data:writeentry + mod/feedback:addinstance + mod/feedback:complete + mod/feedback:createprivatetemplate + mod/feedback:createpublictemplate + mod/feedback:deletesubmissions + mod/feedback:deletetemplate + mod/feedback:edititems + mod/feedback:mapcourse + mod/feedback:receivemail + mod/feedback:view + mod/feedback:viewanalysepage + mod/feedback:viewreports + mod/folder:addinstance + mod/folder:managefiles + mod/folder:view + mod/forum:addinstance + mod/forum:addnews + mod/forum:addquestion + mod/forum:allowforcesubscribe + mod/forum:canoverridecutoff + mod/forum:canoverridediscussionlock + mod/forum:canposttomygroups + mod/forum:cantogglefavourite + mod/forum:createattachment + mod/forum:deleteanypost + mod/forum:deleteownpost + mod/forum:editanypost + mod/forum:exportdiscussion + mod/forum:exportforum + mod/forum:exportownpost + mod/forum:exportpost + mod/forum:grade + mod/forum:managesubscriptions + mod/forum:movediscussions + mod/forum:pindiscussions + mod/forum:postprivatereply + mod/forum:postwithoutthrottling + mod/forum:rate + mod/forum:readprivatereplies + mod/forum:replynews + mod/forum:replypost + mod/forum:splitdiscussions + mod/forum:startdiscussion + mod/forum:viewallratings + mod/forum:viewanyrating + mod/forum:viewdiscussion + mod/forum:viewhiddentimedposts + mod/forum:viewqandawithoutposting + mod/forum:viewrating + mod/forum:viewsubscribers + mod/glossary:addinstance + mod/glossary:approve + mod/glossary:comment + mod/glossary:export + mod/glossary:exportentry + mod/glossary:exportownentry + mod/glossary:import + mod/glossary:managecategories + mod/glossary:managecomments + mod/glossary:manageentries + mod/glossary:rate + mod/glossary:view + mod/glossary:viewallratings + mod/glossary:viewanyrating + mod/glossary:viewrating + mod/glossary:write + mod/h5pactivity:addinstance + mod/h5pactivity:reviewattempts + mod/h5pactivity:submit + mod/h5pactivity:view + mod/imscp:addinstance + mod/imscp:view + mod/label:addinstance + mod/label:view + mod/lesson:addinstance + mod/lesson:edit + mod/lesson:grade + mod/lesson:manage + mod/lesson:manageoverrides + mod/lesson:view + mod/lesson:viewreports + mod/lti:addcoursetool + mod/lti:addinstance + mod/lti:addmanualinstance + mod/lti:addpreconfiguredinstance + mod/lti:admin + mod/lti:manage + mod/lti:requesttooladd + mod/lti:view + mod/page:addinstance + mod/page:view + mod/quiz:addinstance + mod/quiz:attempt + mod/quiz:deleteattempts + mod/quiz:emailconfirmsubmission + mod/quiz:emailnotifysubmission + mod/quiz:emailwarnoverdue + mod/quiz:grade + mod/quiz:ignoretimelimits + mod/quiz:manage + mod/quiz:manageoverrides + mod/quiz:preview + mod/quiz:regrade + mod/quiz:reviewmyattempts + mod/resource:addinstance + mod/resource:view + mod/scorm:addinstance + mod/scorm:deleteownresponses + mod/scorm:deleteresponses + mod/scorm:savetrack + mod/scorm:skipview + mod/scorm:viewreport + mod/scorm:viewscores + mod/survey:addinstance + mod/survey:download + mod/survey:participate + mod/survey:readresponses + mod/url:addinstance + mod/url:view + mod/wiki:addinstance + mod/wiki:createpage + mod/wiki:editcomment + mod/wiki:editpage + mod/wiki:managecomment + mod/wiki:managefiles + mod/wiki:managewiki + mod/wiki:overridelock + mod/wiki:viewcomment + mod/wiki:viewpage + mod/workshop:addinstance + mod/workshop:allocate + mod/workshop:deletesubmissions + mod/workshop:editdimensions + mod/workshop:exportsubmissions + mod/workshop:ignoredeadlines + mod/workshop:manageexamples + mod/workshop:overridegrades + mod/workshop:peerassess + mod/workshop:publishsubmissions + mod/workshop:submit + mod/workshop:switchphase + mod/workshop:view + mod/workshop:viewallassessments + mod/workshop:viewallsubmissions + mod/workshop:viewauthornames + mod/workshop:viewauthorpublished + mod/workshop:viewpublishedsubmissions + mod/workshop:viewreviewernames + moodle/analytics:listinsights + moodle/analytics:listowninsights + moodle/analytics:managemodels + moodle/backup:anonymise + moodle/backup:backupactivity + moodle/backup:backupcourse + moodle/backup:backupsection + moodle/backup:backuptargetimport + moodle/backup:configure + moodle/backup:downloadfile + moodle/backup:userinfo + moodle/badges:awardbadge + moodle/badges:configurecriteria + moodle/badges:configuredetails + moodle/badges:configuremessages + moodle/badges:createbadge + moodle/badges:deletebadge + moodle/badges:earnbadge + moodle/badges:manageglobalsettings + moodle/badges:manageownbadges + moodle/badges:revokebadge + moodle/badges:viewawarded + moodle/badges:viewbadges + moodle/badges:viewotherbadges + moodle/block:edit + moodle/block:view + moodle/blog:create + moodle/blog:manageentries + moodle/blog:manageexternal + moodle/blog:search + moodle/blog:view + moodle/blog:viewdrafts + moodle/calendar:manageentries + moodle/calendar:managegroupentries + moodle/calendar:manageownentries + moodle/category:manage + moodle/cohort:assign + moodle/cohort:manage + moodle/cohort:view + moodle/comment:delete + moodle/comment:post + moodle/comment:view + moodle/competency:competencygrade + moodle/competency:competencymanage + moodle/competency:competencyview + moodle/competency:coursecompetencyconfigure + moodle/competency:coursecompetencygradable + moodle/competency:coursecompetencymanage + moodle/competency:coursecompetencyview + moodle/competency:evidencedelete + moodle/competency:plancomment + moodle/competency:plancommentown + moodle/competency:planmanage + moodle/competency:planmanagedraft + moodle/competency:planmanageown + moodle/competency:planmanageowndraft + moodle/competency:planrequestreview + moodle/competency:planrequestreviewown + moodle/competency:planreview + moodle/competency:planview + moodle/competency:planviewdraft + moodle/competency:planviewown + moodle/competency:planviewowndraft + moodle/competency:templatemanage + moodle/competency:templateview + moodle/competency:usercompetencycomment + moodle/competency:usercompetencycommentown + moodle/competency:usercompetencyrequestreview + moodle/competency:usercompetencyrequestreviewown + moodle/competency:usercompetencyreview + moodle/competency:usercompetencyview + moodle/competency:userevidencemanage + moodle/competency:userevidencemanageown + moodle/competency:userevidenceview + moodle/contentbank:access + moodle/contentbank:deleteanycontent + moodle/contentbank:deleteowncontent + moodle/contentbank:manageanycontent + moodle/contentbank:manageowncontent + moodle/contentbank:upload + moodle/contentbank:useeditor + moodle/course:activityvisibility + moodle/course:bulkmessaging + moodle/course:changecategory + moodle/course:changefullname + moodle/course:changeidnumber + moodle/course:changelockedcustomfields + moodle/course:changeshortname + moodle/course:changesummary + moodle/course:configurecustomfields + moodle/course:create + moodle/course:creategroupconversations + moodle/course:delete + moodle/course:enrolconfig + moodle/course:enrolreview + moodle/course:ignoreavailabilityrestrictions + moodle/course:ignorefilesizelimits + moodle/course:isincompletionreports + moodle/course:manageactivities + moodle/course:managefiles + moodle/course:managegroups + moodle/course:managescales + moodle/course:markcomplete + moodle/course:movesections + moodle/course:overridecompletion + moodle/course:recommendactivity + moodle/course:renameroles + moodle/course:request + moodle/course:reset + moodle/course:reviewotherusers + moodle/course:sectionvisibility + moodle/course:setcurrentsection + moodle/course:setforcedlanguage + moodle/course:tag + moodle/course:togglecompletion + moodle/course:update + moodle/course:useremail + moodle/course:viewhiddenactivities + moodle/course:viewscales + moodle/course:viewsuspendedusers + moodle/course:visibility + moodle/filter:manage + moodle/grade:edit + moodle/grade:export + moodle/grade:hide + moodle/grade:import + moodle/grade:lock + moodle/grade:manage + moodle/grade:managegradingforms + moodle/grade:manageletters + moodle/grade:manageoutcomes + moodle/grade:managesharedforms + moodle/grade:sharegradingforms + moodle/grade:unlock + moodle/grade:view + moodle/grade:viewall + moodle/grade:viewhidden + moodle/h5p:deploy + moodle/h5p:setdisplayoptions + moodle/h5p:updatelibraries + moodle/my:configsyspages + moodle/my:manageblocks + moodle/notes:manage + moodle/notes:view + moodle/portfolio:export + moodle/question:add + moodle/question:config + moodle/question:editall + moodle/question:editmine + moodle/question:flag + moodle/question:managecategory + moodle/question:moveall + moodle/question:movemine + moodle/question:tagall + moodle/question:tagmine + moodle/question:useall + moodle/question:usemine + moodle/question:viewall + moodle/question:viewmine + moodle/rating:rate + moodle/rating:view + moodle/rating:viewall + moodle/rating:viewany + moodle/restore:configure + moodle/restore:createuser + moodle/restore:restoreactivity + moodle/restore:restorecourse + moodle/restore:restoresection + moodle/restore:restoretargetimport + moodle/restore:rolldates + moodle/restore:uploadfile + moodle/restore:userinfo + moodle/restore:viewautomatedfilearea + moodle/role:assign + moodle/role:manage + moodle/role:override + moodle/role:review + moodle/role:safeoverride + moodle/role:switchroles + moodle/search:query + moodle/site:approvecourse + moodle/site:config + moodle/site:configview + moodle/site:deleteanymessage + moodle/site:deleteownmessage + moodle/site:doclinks + moodle/site:forcelanguage + moodle/site:maintenanceaccess + moodle/site:manageallmessaging + moodle/site:manageblocks + moodle/site:managecontextlocks + moodle/site:messageanyuser + moodle/site:mnetlogintoremote + moodle/site:readallmessages + moodle/site:sendmessage + moodle/site:trustcontent + moodle/site:uploadusers + moodle/site:viewanonymousevents + moodle/site:viewfullnames + moodle/site:viewparticipants + moodle/site:viewreports + moodle/site:viewuseridentity + moodle/tag:edit + moodle/tag:editblocks + moodle/tag:flag + moodle/tag:manage + moodle/user:changeownpassword + moodle/user:create + moodle/user:delete + moodle/user:editmessageprofile + moodle/user:editownmessageprofile + moodle/user:editownprofile + moodle/user:editprofile + moodle/user:ignoreuserquota + moodle/user:loginas + moodle/user:manageblocks + moodle/user:manageownblocks + moodle/user:manageownfiles + moodle/user:managesyspages + moodle/user:readuserblogs + moodle/user:readuserposts + moodle/user:update + moodle/user:viewalldetails + moodle/user:viewlastip + moodle/user:viewuseractivitiesreport + moodle/user:viewuseractivitiesreport + qtype/lti:addcoursetool + qtype/lti:adddefaultinstance + qtype/lti:addgloballypreconfigedtoolinstance + qtype/lti:addinstance + qtype/lti:admin + qtype/lti:backupcourse + qtype/lti:manage + qtype/lti:regradelti + qtype/lti:requesttooladd + qtype/lti:view + quizaccess/seb:manage_filemanager_sebconfigfile + quizaccess/seb:manage_seb_activateurlfiltering + quizaccess/seb:manage_seb_allowedbrowserexamkeys + quizaccess/seb:manage_seb_allowreloadinexam + quizaccess/seb:manage_seb_allowspellchecking + quizaccess/seb:manage_seb_allowuserquitseb + quizaccess/seb:manage_seb_enableaudiocontrol + quizaccess/seb:manage_seb_expressionsallowed + quizaccess/seb:manage_seb_expressionsblocked + quizaccess/seb:manage_seb_filterembeddedcontent + quizaccess/seb:manage_seb_linkquitseb + quizaccess/seb:manage_seb_muteonstartup + quizaccess/seb:manage_seb_quitpassword + quizaccess/seb:manage_seb_regexallowed + quizaccess/seb:manage_seb_regexblocked + quizaccess/seb:manage_seb_requiresafeexambrowser + quizaccess/seb:manage_seb_showkeyboardlayout + quizaccess/seb:manage_seb_showreloadbutton + quizaccess/seb:manage_seb_showsebdownloadlink + quizaccess/seb:manage_seb_showsebtaskbar + quizaccess/seb:manage_seb_showtime + quizaccess/seb:manage_seb_showwificontrol + quizaccess/seb:manage_seb_templateid + quizaccess/seb:manage_seb_userconfirmquit + quizaccess/seb:managetemplates + quizaccess/sebserver:managesebserver + quizaccess/wifiresilience:adminmessages + quizaccess/wifiresilience:browserchecks + quizaccess/wifiresilience:inspectresponses + quizaccess/wifiresilience:localresponses + quizaccess/wifiresilience:uploadresponses + quizaccess/wifiresilience:viewlivedevices + quizaccess/wifiresilience:viewtechchecks + quiz/grading:viewidnumber + quiz/grading:viewstudentnames + quiz/statistics:view + report/completion:view + report/customsql:definequeries + report/customsql:managecategories + report/customsql:view + report/loglive:view + report/log:view + report/log:viewtoday + report/outline:view + report/outline:viewuserreport + report/participation:view + report/performance:view + report/progress:view + report/questioninstances:view + report/security:view + report/stats:view + report/status:view + report/usersessions:manageownsessions + repository/areafiles:view + repository/boxnet:view + repository/contentbank:accesscoursecategorycontent + repository/contentbank:accesscoursecontent + repository/contentbank:accessgeneralcontent + repository/contentbank:view + repository/coursefiles:view + repository/dropbox:view + repository/equella:view + repository/filesystem:view + repository/flickr_public:view + repository/flickr:view + repository/googledocs:view + repository/local:view + repository/merlot:view + repository/nextcloud:view + repository/onedrive:view + repository/opencast:view + repository/picasa:view + repository/recent:view + repository/s3:view + repository/skydrive:view + repository/upload:view + repository/url:view + repository/user:view + repository/webdav:view + repository/wikimedia:view + repository/youtube:view + tool/coursedates:setdates + tool/customlang:edit + tool/customlang:view + tool/dataprivacy:downloadallrequests + tool/dataprivacy:downloadownrequest + tool/dataprivacy:makedatadeletionrequestsforchildren + tool/dataprivacy:makedatarequestsforchildren + tool/dataprivacy:managedataregistry + tool/dataprivacy:managedatarequests + tool/dataprivacy:requestdelete + tool/dataprivacy:requestdeleteforotheruser + tool/lpmigrate:frameworksmigrate + tool/monitor:managerules + tool/monitor:managetool + tool/monitor:subscribe + tool/opencast:externalapi + tool/opencast:instructor + tool/opencast:learner + tool/policy:accept + tool/policy:acceptbehalf + tool/policy:managedocs + tool/policy:viewacceptances + tool/recyclebin:deleteitems + tool/recyclebin:restoreitems + tool/recyclebin:viewitems + tool/uploaduser:uploaduserpictures + tool/usertours:managetours + webservice/soap:use + webservice/xmlrpc:use + mod/quiz:view + mod/quiz:viewreports + moodle/category:viewcourselist + moodle/category:viewhiddencategories + moodle/course:view + moodle/course:viewhiddencourses + moodle/course:viewhiddensections + moodle/course:viewhiddenuserfields + moodle/course:viewparticipants + moodle/site:accessallgroups + moodle/user:viewdetails + moodle/user:viewhiddendetails + moodle/webservice:createmobiletoken + moodle/webservice:createtoken + quizaccess/seb:bypassseb + report/courseoverview:view + webservice/rest:use + + From c3bb795840c77b8b1a0bbd0bf5467776f36bc874 Mon Sep 17 00:00:00 2001 From: Andreas Hefti Date: Wed, 4 Oct 2023 08:56:03 +0200 Subject: [PATCH 08/31] Update webservice_seb-server.xml added allow --- docs/files/webservice_seb-server.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/files/webservice_seb-server.xml b/docs/files/webservice_seb-server.xml index a01f32de..c40f4128 100644 --- a/docs/files/webservice_seb-server.xml +++ b/docs/files/webservice_seb-server.xml @@ -631,7 +631,6 @@ quizaccess/seb:manage_seb_templateid quizaccess/seb:manage_seb_userconfirmquit quizaccess/seb:managetemplates - quizaccess/sebserver:managesebserver quizaccess/wifiresilience:adminmessages quizaccess/wifiresilience:browserchecks quizaccess/wifiresilience:inspectresponses @@ -733,5 +732,11 @@ quizaccess/seb:bypassseb report/courseoverview:view webservice/rest:use + + moodle/user:update + moodle/course:useremail + moodle/backup:backupcourse + mod/quiz:manage + quizaccess/sebserver:managesebserver From 18487a02049d61d8bbba460191b230474709c09b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 20:48:53 +0000 Subject: [PATCH 09/31] Bump readthedocs-sphinx-search from 0.1.1 to 0.3.2 in /docs Bumps [readthedocs-sphinx-search](https://github.com/readthedocs/readthedocs-sphinx-search) from 0.1.1 to 0.3.2. - [Changelog](https://github.com/readthedocs/readthedocs-sphinx-search/blob/main/CHANGELOG.rst) - [Commits](https://github.com/readthedocs/readthedocs-sphinx-search/compare/0.1.1...0.3.2) --- updated-dependencies: - dependency-name: readthedocs-sphinx-search dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index eb2a5188..c46217a6 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,5 @@ docutils<0.18 sphinx==5.3.0 sphinx_rtd_theme==1.1.1 -readthedocs-sphinx-search==0.1.1 +readthedocs-sphinx-search==0.3.2 urllib3==1.26.13 \ No newline at end of file From e8587806ef719ba455ec4e612e517a8943c18ca2 Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 25 Jan 2024 12:26:00 +0100 Subject: [PATCH 10/31] SEBSERV-502 deprecation note --- .readthedocs.yaml | 35 ++ docs/conf.py | 2 +- docs/exam_proctoring.rst | 8 + docs/files/webservice_seb-server.xml | 742 +-------------------------- docs/lmssetup.rst | 6 +- docs/monitoring.rst | 8 + docs/requirements.txt | 2 +- 7 files changed, 57 insertions(+), 746 deletions(-) create mode 100644 .readthedocs.yaml diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 00000000..60516d2d --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,35 @@ +# Read the Docs configuration file for Sphinx projects +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the OS, Python version and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.12" + # You can also specify other tool versions: + # nodejs: "20" + # rust: "1.70" + # golang: "1.20" + +# Build documentation in the "docs/" directory with Sphinx +sphinx: + configuration: docs/conf.py + # You can configure Sphinx to use a different builder, for instance use the dirhtml builder for simpler URLs + # builder: "dirhtml" + # Fail on all warnings to avoid broken references + # fail_on_warning: true + +# Optionally build your docs in additional formats such as PDF and ePub +# formats: +# - pdf +# - epub + +# Optional but recommended, declare the Python requirements required +# to build your documentation +# See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html +python: + install: + - requirements: docs/requirements.txt \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 8fba51fa..70f190b8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -43,7 +43,7 @@ extensions = [ 'sphinx.ext.todo', 'sphinx.ext.imgmath', 'sphinx.ext.viewcode', - 'sphinx.ext.githubpages', + 'sphinx.ext.githubpages' ] # Add any paths that contain templates here, relative to this directory. diff --git a/docs/exam_proctoring.rst b/docs/exam_proctoring.rst index e80833cf..cd82a020 100644 --- a/docs/exam_proctoring.rst +++ b/docs/exam_proctoring.rst @@ -3,6 +3,14 @@ Optional Live Proctoring ======================== +.. attention:: + + Deprecation + + The SEB Server live proctoring integration with Zoom and Jitsi Meet will be deprecated within the next upcoming version of SEB Server 1.6. + + This means live proctoring is still available for dedicated SEB versions, but not actively maintained and supported any more. + Live proctoring is a new and yet experimental feature of SEB and SEB Server. The feature is fully optional and not enabled by default. The main goal of the live proctoring feature is to support the integration of an external meeting service like Jitsi Meet or Zoom for example, within a SEB and SEB Server setup for an exam. diff --git a/docs/files/webservice_seb-server.xml b/docs/files/webservice_seb-server.xml index c40f4128..7c723a2d 100644 --- a/docs/files/webservice_seb-server.xml +++ b/docs/files/webservice_seb-server.xml @@ -1,742 +1,2 @@ - - webservice_seb-server - webservice_SEB-Server - - - - system - - - - - - - atto/h5p:addembed - atto/recordrtc:recordaudio - atto/recordrtc:recordvideo - auth/oauth2:managelinkedlogins - block/activity_modules:addinstance - block/activity_results:addinstance - block/admin_bookmarks:addinstance - block/admin_bookmarks:myaddinstance - block/badges:addinstance - block/badges:myaddinstance - block/blog_menu:addinstance - block/blog_recent:addinstance - block/blog_tags:addinstance - block/calendar_month:addinstance - block/calendar_month:myaddinstance - block/calendar_upcoming:addinstance - block/calendar_upcoming:myaddinstance - block/comments:addinstance - block/comments:myaddinstance - block/completionstatus:addinstance - block/course_list:addinstance - block/course_list:myaddinstance - block/course_summary:addinstance - block/feedback:addinstance - block/globalsearch:addinstance - block/globalsearch:myaddinstance - block/glossary_random:addinstance - block/glossary_random:myaddinstance - block/html:addinstance - block/html:myaddinstance - block/login:addinstance - block/lp:addinstance - block/lp:myaddinstance - block/mentees:addinstance - block/mentees:myaddinstance - block/mnet_hosts:addinstance - block/mnet_hosts:myaddinstance - block/myoverview:myaddinstance - block/myprofile:addinstance - block/myprofile:myaddinstance - block/navigation:addinstance - block/navigation:myaddinstance - block/news_items:addinstance - block/news_items:myaddinstance - block/onlinesurvey:addinstance - block/onlinesurvey:myaddinstance - block/onlinesurvey:view - block/onlinesurvey:view_debugdetails - block/online_users:addinstance - block/online_users:myaddinstance - block/online_users:viewlist - block/opencast:addinstance - block/opencast:addlti - block/opencast:addltiepisode - block/opencast:addvideo - block/opencast:createseriesforcourse - block/opencast:defineseriesforcourse - block/opencast:deleteevent - block/opencast:myaddinstance - block/opencast:unassignevent - block/opencast:viewunpublishedvideos - block/private_files:addinstance - block/private_files:myaddinstance - block/quiz_results:addinstance - block/recent_activity:addinstance - block/recent_activity:viewaddupdatemodule - block/recent_activity:viewdeletemodule - block/recentlyaccessedcourses:myaddinstance - block/recentlyaccesseditems:myaddinstance - block/rss_client:addinstance - block/rss_client:manageanyfeeds - block/rss_client:manageownfeeds - block/rss_client:myaddinstance - block/search_forums:addinstance - block/section_links:addinstance - block/selfcompletion:addinstance - block/settings:addinstance - block/settings:myaddinstance - block/site_main_menu:addinstance - block/social_activities:addinstance - block/starredcourses:myaddinstance - block/tag_flickr:addinstance - block/tags:addinstance - block/tags:myaddinstance - block/tag_youtube:addinstance - block/timeline:myaddinstance - booktool/exportimscp:export - booktool/importhtml:import - booktool/print:print - contenttype/h5p:access - contenttype/h5p:upload - contenttype/h5p:useeditor - enrol/category:config - enrol/category:synchronised - enrol/cohort:config - enrol/cohort:unenrol - enrol/database:config - enrol/database:unenrol - enrol/flatfile:manage - enrol/flatfile:unenrol - enrol/guest:config - enrol/imsenterprise:config - enrol/ldap:manage - enrol/lti:config - enrol/lti:unenrol - enrol/manual:config - enrol/manual:enrol - enrol/manual:manage - enrol/manual:unenrol - enrol/manual:unenrolself - enrol/meta:config - enrol/meta:selectaslinked - enrol/meta:unenrol - enrol/mnet:config - enrol/paypal:config - enrol/paypal:manage - enrol/paypal:unenrol - enrol/paypal:unenrolself - enrol/self:config - enrol/self:holdkey - enrol/self:manage - enrol/self:unenrol - enrol/self:unenrolself - format/columns:changecolumns - format/grid:changeimagecontainersize - format/grid:changeimagecontainerstyle - format/grid:changeimageresizemethod - format/topcoll:changecolour - format/topcoll:changelayout - format/topcoll:changetogglealignment - format/topcoll:changetoggleiconset - forumreport/summary:view - forumreport/summary:viewall - gradeexport/ods:publish - gradeexport/ods:view - gradeexport/txt:publish - gradeexport/txt:view - gradeexport/xls:publish - gradeexport/xls:view - gradeexport/xml:publish - gradeexport/xml:view - gradeimport/csv:view - gradeimport/direct:view - gradeimport/xml:publish - gradeimport/xml:view - gradereport/grader:view - gradereport/history:view - gradereport/outcomes:view - gradereport/overview:view - gradereport/singleview:view - gradereport/user:view - message/airnotifier:managedevice - mod/assign:addinstance - mod/assign:editothersubmission - mod/assign:exportownsubmission - mod/assign:grade - mod/assign:grantextension - mod/assign:manageallocations - mod/assign:managegrades - mod/assign:manageoverrides - mod/assignment:addinstance - mod/assignment:exportownsubmission - mod/assignment:grade - mod/assignment:submit - mod/assignment:view - mod/assign:receivegradernotifications - mod/assign:releasegrades - mod/assign:revealidentities - mod/assign:reviewgrades - mod/assign:showhiddengrader - mod/assign:submit - mod/assign:view - mod/assign:viewblinddetails - mod/assign:viewgrades - mod/book:addinstance - mod/book:edit - mod/book:read - mod/book:viewhiddenchapters - mod/chat:addinstance - mod/chat:chat - mod/chat:deletelog - mod/chat:exportparticipatedsession - mod/chat:exportsession - mod/chat:readlog - mod/chat:view - mod/choice:addinstance - mod/choice:choose - mod/choice:deleteresponses - mod/choice:downloadresponses - mod/choice:readresponses - mod/choice:view - mod/data:addinstance - mod/data:approve - mod/data:comment - mod/data:exportallentries - mod/data:exportentry - mod/data:exportownentry - mod/data:exportuserinfo - mod/data:managecomments - mod/data:manageentries - mod/data:managetemplates - mod/data:manageuserpresets - mod/data:rate - mod/data:view - mod/data:viewallratings - mod/data:viewalluserpresets - mod/data:viewanyrating - mod/data:viewentry - mod/data:viewrating - mod/data:writeentry - mod/feedback:addinstance - mod/feedback:complete - mod/feedback:createprivatetemplate - mod/feedback:createpublictemplate - mod/feedback:deletesubmissions - mod/feedback:deletetemplate - mod/feedback:edititems - mod/feedback:mapcourse - mod/feedback:receivemail - mod/feedback:view - mod/feedback:viewanalysepage - mod/feedback:viewreports - mod/folder:addinstance - mod/folder:managefiles - mod/folder:view - mod/forum:addinstance - mod/forum:addnews - mod/forum:addquestion - mod/forum:allowforcesubscribe - mod/forum:canoverridecutoff - mod/forum:canoverridediscussionlock - mod/forum:canposttomygroups - mod/forum:cantogglefavourite - mod/forum:createattachment - mod/forum:deleteanypost - mod/forum:deleteownpost - mod/forum:editanypost - mod/forum:exportdiscussion - mod/forum:exportforum - mod/forum:exportownpost - mod/forum:exportpost - mod/forum:grade - mod/forum:managesubscriptions - mod/forum:movediscussions - mod/forum:pindiscussions - mod/forum:postprivatereply - mod/forum:postwithoutthrottling - mod/forum:rate - mod/forum:readprivatereplies - mod/forum:replynews - mod/forum:replypost - mod/forum:splitdiscussions - mod/forum:startdiscussion - mod/forum:viewallratings - mod/forum:viewanyrating - mod/forum:viewdiscussion - mod/forum:viewhiddentimedposts - mod/forum:viewqandawithoutposting - mod/forum:viewrating - mod/forum:viewsubscribers - mod/glossary:addinstance - mod/glossary:approve - mod/glossary:comment - mod/glossary:export - mod/glossary:exportentry - mod/glossary:exportownentry - mod/glossary:import - mod/glossary:managecategories - mod/glossary:managecomments - mod/glossary:manageentries - mod/glossary:rate - mod/glossary:view - mod/glossary:viewallratings - mod/glossary:viewanyrating - mod/glossary:viewrating - mod/glossary:write - mod/h5pactivity:addinstance - mod/h5pactivity:reviewattempts - mod/h5pactivity:submit - mod/h5pactivity:view - mod/imscp:addinstance - mod/imscp:view - mod/label:addinstance - mod/label:view - mod/lesson:addinstance - mod/lesson:edit - mod/lesson:grade - mod/lesson:manage - mod/lesson:manageoverrides - mod/lesson:view - mod/lesson:viewreports - mod/lti:addcoursetool - mod/lti:addinstance - mod/lti:addmanualinstance - mod/lti:addpreconfiguredinstance - mod/lti:admin - mod/lti:manage - mod/lti:requesttooladd - mod/lti:view - mod/page:addinstance - mod/page:view - mod/quiz:addinstance - mod/quiz:attempt - mod/quiz:deleteattempts - mod/quiz:emailconfirmsubmission - mod/quiz:emailnotifysubmission - mod/quiz:emailwarnoverdue - mod/quiz:grade - mod/quiz:ignoretimelimits - mod/quiz:manage - mod/quiz:manageoverrides - mod/quiz:preview - mod/quiz:regrade - mod/quiz:reviewmyattempts - mod/resource:addinstance - mod/resource:view - mod/scorm:addinstance - mod/scorm:deleteownresponses - mod/scorm:deleteresponses - mod/scorm:savetrack - mod/scorm:skipview - mod/scorm:viewreport - mod/scorm:viewscores - mod/survey:addinstance - mod/survey:download - mod/survey:participate - mod/survey:readresponses - mod/url:addinstance - mod/url:view - mod/wiki:addinstance - mod/wiki:createpage - mod/wiki:editcomment - mod/wiki:editpage - mod/wiki:managecomment - mod/wiki:managefiles - mod/wiki:managewiki - mod/wiki:overridelock - mod/wiki:viewcomment - mod/wiki:viewpage - mod/workshop:addinstance - mod/workshop:allocate - mod/workshop:deletesubmissions - mod/workshop:editdimensions - mod/workshop:exportsubmissions - mod/workshop:ignoredeadlines - mod/workshop:manageexamples - mod/workshop:overridegrades - mod/workshop:peerassess - mod/workshop:publishsubmissions - mod/workshop:submit - mod/workshop:switchphase - mod/workshop:view - mod/workshop:viewallassessments - mod/workshop:viewallsubmissions - mod/workshop:viewauthornames - mod/workshop:viewauthorpublished - mod/workshop:viewpublishedsubmissions - mod/workshop:viewreviewernames - moodle/analytics:listinsights - moodle/analytics:listowninsights - moodle/analytics:managemodels - moodle/backup:anonymise - moodle/backup:backupactivity - moodle/backup:backupcourse - moodle/backup:backupsection - moodle/backup:backuptargetimport - moodle/backup:configure - moodle/backup:downloadfile - moodle/backup:userinfo - moodle/badges:awardbadge - moodle/badges:configurecriteria - moodle/badges:configuredetails - moodle/badges:configuremessages - moodle/badges:createbadge - moodle/badges:deletebadge - moodle/badges:earnbadge - moodle/badges:manageglobalsettings - moodle/badges:manageownbadges - moodle/badges:revokebadge - moodle/badges:viewawarded - moodle/badges:viewbadges - moodle/badges:viewotherbadges - moodle/block:edit - moodle/block:view - moodle/blog:create - moodle/blog:manageentries - moodle/blog:manageexternal - moodle/blog:search - moodle/blog:view - moodle/blog:viewdrafts - moodle/calendar:manageentries - moodle/calendar:managegroupentries - moodle/calendar:manageownentries - moodle/category:manage - moodle/cohort:assign - moodle/cohort:manage - moodle/cohort:view - moodle/comment:delete - moodle/comment:post - moodle/comment:view - moodle/competency:competencygrade - moodle/competency:competencymanage - moodle/competency:competencyview - moodle/competency:coursecompetencyconfigure - moodle/competency:coursecompetencygradable - moodle/competency:coursecompetencymanage - moodle/competency:coursecompetencyview - moodle/competency:evidencedelete - moodle/competency:plancomment - moodle/competency:plancommentown - moodle/competency:planmanage - moodle/competency:planmanagedraft - moodle/competency:planmanageown - moodle/competency:planmanageowndraft - moodle/competency:planrequestreview - moodle/competency:planrequestreviewown - moodle/competency:planreview - moodle/competency:planview - moodle/competency:planviewdraft - moodle/competency:planviewown - moodle/competency:planviewowndraft - moodle/competency:templatemanage - moodle/competency:templateview - moodle/competency:usercompetencycomment - moodle/competency:usercompetencycommentown - moodle/competency:usercompetencyrequestreview - moodle/competency:usercompetencyrequestreviewown - moodle/competency:usercompetencyreview - moodle/competency:usercompetencyview - moodle/competency:userevidencemanage - moodle/competency:userevidencemanageown - moodle/competency:userevidenceview - moodle/contentbank:access - moodle/contentbank:deleteanycontent - moodle/contentbank:deleteowncontent - moodle/contentbank:manageanycontent - moodle/contentbank:manageowncontent - moodle/contentbank:upload - moodle/contentbank:useeditor - moodle/course:activityvisibility - moodle/course:bulkmessaging - moodle/course:changecategory - moodle/course:changefullname - moodle/course:changeidnumber - moodle/course:changelockedcustomfields - moodle/course:changeshortname - moodle/course:changesummary - moodle/course:configurecustomfields - moodle/course:create - moodle/course:creategroupconversations - moodle/course:delete - moodle/course:enrolconfig - moodle/course:enrolreview - moodle/course:ignoreavailabilityrestrictions - moodle/course:ignorefilesizelimits - moodle/course:isincompletionreports - moodle/course:manageactivities - moodle/course:managefiles - moodle/course:managegroups - moodle/course:managescales - moodle/course:markcomplete - moodle/course:movesections - moodle/course:overridecompletion - moodle/course:recommendactivity - moodle/course:renameroles - moodle/course:request - moodle/course:reset - moodle/course:reviewotherusers - moodle/course:sectionvisibility - moodle/course:setcurrentsection - moodle/course:setforcedlanguage - moodle/course:tag - moodle/course:togglecompletion - moodle/course:update - moodle/course:useremail - moodle/course:viewhiddenactivities - moodle/course:viewscales - moodle/course:viewsuspendedusers - moodle/course:visibility - moodle/filter:manage - moodle/grade:edit - moodle/grade:export - moodle/grade:hide - moodle/grade:import - moodle/grade:lock - moodle/grade:manage - moodle/grade:managegradingforms - moodle/grade:manageletters - moodle/grade:manageoutcomes - moodle/grade:managesharedforms - moodle/grade:sharegradingforms - moodle/grade:unlock - moodle/grade:view - moodle/grade:viewall - moodle/grade:viewhidden - moodle/h5p:deploy - moodle/h5p:setdisplayoptions - moodle/h5p:updatelibraries - moodle/my:configsyspages - moodle/my:manageblocks - moodle/notes:manage - moodle/notes:view - moodle/portfolio:export - moodle/question:add - moodle/question:config - moodle/question:editall - moodle/question:editmine - moodle/question:flag - moodle/question:managecategory - moodle/question:moveall - moodle/question:movemine - moodle/question:tagall - moodle/question:tagmine - moodle/question:useall - moodle/question:usemine - moodle/question:viewall - moodle/question:viewmine - moodle/rating:rate - moodle/rating:view - moodle/rating:viewall - moodle/rating:viewany - moodle/restore:configure - moodle/restore:createuser - moodle/restore:restoreactivity - moodle/restore:restorecourse - moodle/restore:restoresection - moodle/restore:restoretargetimport - moodle/restore:rolldates - moodle/restore:uploadfile - moodle/restore:userinfo - moodle/restore:viewautomatedfilearea - moodle/role:assign - moodle/role:manage - moodle/role:override - moodle/role:review - moodle/role:safeoverride - moodle/role:switchroles - moodle/search:query - moodle/site:approvecourse - moodle/site:config - moodle/site:configview - moodle/site:deleteanymessage - moodle/site:deleteownmessage - moodle/site:doclinks - moodle/site:forcelanguage - moodle/site:maintenanceaccess - moodle/site:manageallmessaging - moodle/site:manageblocks - moodle/site:managecontextlocks - moodle/site:messageanyuser - moodle/site:mnetlogintoremote - moodle/site:readallmessages - moodle/site:sendmessage - moodle/site:trustcontent - moodle/site:uploadusers - moodle/site:viewanonymousevents - moodle/site:viewfullnames - moodle/site:viewparticipants - moodle/site:viewreports - moodle/site:viewuseridentity - moodle/tag:edit - moodle/tag:editblocks - moodle/tag:flag - moodle/tag:manage - moodle/user:changeownpassword - moodle/user:create - moodle/user:delete - moodle/user:editmessageprofile - moodle/user:editownmessageprofile - moodle/user:editownprofile - moodle/user:editprofile - moodle/user:ignoreuserquota - moodle/user:loginas - moodle/user:manageblocks - moodle/user:manageownblocks - moodle/user:manageownfiles - moodle/user:managesyspages - moodle/user:readuserblogs - moodle/user:readuserposts - moodle/user:update - moodle/user:viewalldetails - moodle/user:viewlastip - moodle/user:viewuseractivitiesreport - moodle/user:viewuseractivitiesreport - qtype/lti:addcoursetool - qtype/lti:adddefaultinstance - qtype/lti:addgloballypreconfigedtoolinstance - qtype/lti:addinstance - qtype/lti:admin - qtype/lti:backupcourse - qtype/lti:manage - qtype/lti:regradelti - qtype/lti:requesttooladd - qtype/lti:view - quizaccess/seb:manage_filemanager_sebconfigfile - quizaccess/seb:manage_seb_activateurlfiltering - quizaccess/seb:manage_seb_allowedbrowserexamkeys - quizaccess/seb:manage_seb_allowreloadinexam - quizaccess/seb:manage_seb_allowspellchecking - quizaccess/seb:manage_seb_allowuserquitseb - quizaccess/seb:manage_seb_enableaudiocontrol - quizaccess/seb:manage_seb_expressionsallowed - quizaccess/seb:manage_seb_expressionsblocked - quizaccess/seb:manage_seb_filterembeddedcontent - quizaccess/seb:manage_seb_linkquitseb - quizaccess/seb:manage_seb_muteonstartup - quizaccess/seb:manage_seb_quitpassword - quizaccess/seb:manage_seb_regexallowed - quizaccess/seb:manage_seb_regexblocked - quizaccess/seb:manage_seb_requiresafeexambrowser - quizaccess/seb:manage_seb_showkeyboardlayout - quizaccess/seb:manage_seb_showreloadbutton - quizaccess/seb:manage_seb_showsebdownloadlink - quizaccess/seb:manage_seb_showsebtaskbar - quizaccess/seb:manage_seb_showtime - quizaccess/seb:manage_seb_showwificontrol - quizaccess/seb:manage_seb_templateid - quizaccess/seb:manage_seb_userconfirmquit - quizaccess/seb:managetemplates - quizaccess/wifiresilience:adminmessages - quizaccess/wifiresilience:browserchecks - quizaccess/wifiresilience:inspectresponses - quizaccess/wifiresilience:localresponses - quizaccess/wifiresilience:uploadresponses - quizaccess/wifiresilience:viewlivedevices - quizaccess/wifiresilience:viewtechchecks - quiz/grading:viewidnumber - quiz/grading:viewstudentnames - quiz/statistics:view - report/completion:view - report/customsql:definequeries - report/customsql:managecategories - report/customsql:view - report/loglive:view - report/log:view - report/log:viewtoday - report/outline:view - report/outline:viewuserreport - report/participation:view - report/performance:view - report/progress:view - report/questioninstances:view - report/security:view - report/stats:view - report/status:view - report/usersessions:manageownsessions - repository/areafiles:view - repository/boxnet:view - repository/contentbank:accesscoursecategorycontent - repository/contentbank:accesscoursecontent - repository/contentbank:accessgeneralcontent - repository/contentbank:view - repository/coursefiles:view - repository/dropbox:view - repository/equella:view - repository/filesystem:view - repository/flickr_public:view - repository/flickr:view - repository/googledocs:view - repository/local:view - repository/merlot:view - repository/nextcloud:view - repository/onedrive:view - repository/opencast:view - repository/picasa:view - repository/recent:view - repository/s3:view - repository/skydrive:view - repository/upload:view - repository/url:view - repository/user:view - repository/webdav:view - repository/wikimedia:view - repository/youtube:view - tool/coursedates:setdates - tool/customlang:edit - tool/customlang:view - tool/dataprivacy:downloadallrequests - tool/dataprivacy:downloadownrequest - tool/dataprivacy:makedatadeletionrequestsforchildren - tool/dataprivacy:makedatarequestsforchildren - tool/dataprivacy:managedataregistry - tool/dataprivacy:managedatarequests - tool/dataprivacy:requestdelete - tool/dataprivacy:requestdeleteforotheruser - tool/lpmigrate:frameworksmigrate - tool/monitor:managerules - tool/monitor:managetool - tool/monitor:subscribe - tool/opencast:externalapi - tool/opencast:instructor - tool/opencast:learner - tool/policy:accept - tool/policy:acceptbehalf - tool/policy:managedocs - tool/policy:viewacceptances - tool/recyclebin:deleteitems - tool/recyclebin:restoreitems - tool/recyclebin:viewitems - tool/uploaduser:uploaduserpictures - tool/usertours:managetours - webservice/soap:use - webservice/xmlrpc:use - mod/quiz:view - mod/quiz:viewreports - moodle/category:viewcourselist - moodle/category:viewhiddencategories - moodle/course:view - moodle/course:viewhiddencourses - moodle/course:viewhiddensections - moodle/course:viewhiddenuserfields - moodle/course:viewparticipants - moodle/site:accessallgroups - moodle/user:viewdetails - moodle/user:viewhiddendetails - moodle/webservice:createmobiletoken - moodle/webservice:createtoken - quizaccess/seb:bypassseb - report/courseoverview:view - webservice/rest:use - - moodle/user:update - moodle/course:useremail - moodle/backup:backupcourse - mod/quiz:manage - quizaccess/sebserver:managesebserver - - +webservice_seb-serverwebservice_SEB-Serversystematto/h5p:addembedatto/recordrtc:recordaudioatto/recordrtc:recordvideoauth/oauth2:managelinkedloginsblock/activity_modules:addinstanceblock/activity_results:addinstanceblock/admin_bookmarks:addinstanceblock/admin_bookmarks:myaddinstanceblock/badges:addinstanceblock/badges:myaddinstanceblock/blog_menu:addinstanceblock/blog_recent:addinstanceblock/blog_tags:addinstanceblock/calendar_month:addinstanceblock/calendar_month:myaddinstanceblock/calendar_upcoming:addinstanceblock/calendar_upcoming:myaddinstanceblock/comments:addinstanceblock/comments:myaddinstanceblock/completionstatus:addinstanceblock/course_list:addinstanceblock/course_list:myaddinstanceblock/course_summary:addinstanceblock/feedback:addinstanceblock/globalsearch:addinstanceblock/globalsearch:myaddinstanceblock/glossary_random:addinstanceblock/glossary_random:myaddinstanceblock/html:addinstanceblock/html:myaddinstanceblock/login:addinstanceblock/lp:addinstanceblock/lp:myaddinstanceblock/mentees:addinstanceblock/mentees:myaddinstanceblock/mnet_hosts:addinstanceblock/mnet_hosts:myaddinstanceblock/myoverview:myaddinstanceblock/myprofile:addinstanceblock/myprofile:myaddinstanceblock/navigation:addinstanceblock/navigation:myaddinstanceblock/news_items:addinstanceblock/news_items:myaddinstanceblock/onlinesurvey:addinstanceblock/onlinesurvey:myaddinstanceblock/onlinesurvey:viewblock/onlinesurvey:view_debugdetailsblock/online_users:addinstanceblock/online_users:myaddinstanceblock/online_users:viewlistblock/opencast:addinstanceblock/opencast:addltiblock/opencast:addltiepisodeblock/opencast:addvideoblock/opencast:createseriesforcourseblock/opencast:defineseriesforcourseblock/opencast:deleteeventblock/opencast:myaddinstanceblock/opencast:unassigneventblock/opencast:viewunpublishedvideosblock/private_files:addinstanceblock/private_files:myaddinstanceblock/quiz_results:addinstanceblock/recent_activity:addinstanceblock/recent_activity:viewaddupdatemoduleblock/recent_activity:viewdeletemoduleblock/recentlyaccessedcourses:myaddinstanceblock/recentlyaccesseditems:myaddinstanceblock/rss_client:addinstanceblock/rss_client:manageanyfeedsblock/rss_client:manageownfeedsblock/rss_client:myaddinstanceblock/search_forums:addinstanceblock/section_links:addinstanceblock/selfcompletion:addinstanceblock/settings:addinstanceblock/settings:myaddinstanceblock/site_main_menu:addinstanceblock/social_activities:addinstanceblock/starredcourses:myaddinstanceblock/tag_flickr:addinstanceblock/tags:addinstanceblock/tags:myaddinstanceblock/tag_youtube:addinstanceblock/timeline:myaddinstancebooktool/exportimscp:exportbooktool/importhtml:importbooktool/print:printcontenttype/h5p:accesscontenttype/h5p:uploadcontenttype/h5p:useeditorenrol/category:configenrol/category:synchronisedenrol/cohort:configenrol/cohort:unenrolenrol/database:configenrol/database:unenrolenrol/flatfile:manageenrol/flatfile:unenrolenrol/guest:configenrol/imsenterprise:configenrol/ldap:manageenrol/lti:configenrol/lti:unenrolenrol/manual:configenrol/manual:enrolenrol/manual:manageenrol/manual:unenrolenrol/manual:unenrolselfenrol/meta:configenrol/meta:selectaslinkedenrol/meta:unenrolenrol/mnet:configenrol/paypal:configenrol/paypal:manageenrol/paypal:unenrolenrol/paypal:unenrolselfenrol/self:configenrol/self:holdkeyenrol/self:manageenrol/self:unenrolenrol/self:unenrolselfformat/columns:changecolumnsformat/grid:changeimagecontainersizeformat/grid:changeimagecontainerstyleformat/grid:changeimageresizemethodformat/topcoll:changecolourformat/topcoll:changelayoutformat/topcoll:changetogglealignmentformat/topcoll:changetoggleiconsetforumreport/summary:viewforumreport/summary:viewallgradeexport/ods:publishgradeexport/ods:viewgradeexport/txt:publishgradeexport/txt:viewgradeexport/xls:publishgradeexport/xls:viewgradeexport/xml:publishgradeexport/xml:viewgradeimport/csv:viewgradeimport/direct:viewgradeimport/xml:publishgradeimport/xml:viewgradereport/grader:viewgradereport/history:viewgradereport/outcomes:viewgradereport/overview:viewgradereport/singleview:viewgradereport/user:viewmessage/airnotifier:managedevicemod/assign:addinstancemod/assign:editothersubmissionmod/assign:exportownsubmissionmod/assign:grademod/assign:grantextensionmod/assign:manageallocationsmod/assign:managegradesmod/assign:manageoverridesmod/assignment:addinstancemod/assignment:exportownsubmissionmod/assignment:grademod/assignment:submitmod/assignment:viewmod/assign:receivegradernotificationsmod/assign:releasegradesmod/assign:revealidentitiesmod/assign:reviewgradesmod/assign:showhiddengradermod/assign:submitmod/assign:viewmod/assign:viewblinddetailsmod/assign:viewgradesmod/book:addinstancemod/book:editmod/book:readmod/book:viewhiddenchaptersmod/chat:addinstancemod/chat:chatmod/chat:deletelogmod/chat:exportparticipatedsessionmod/chat:exportsessionmod/chat:readlogmod/chat:viewmod/choice:addinstancemod/choice:choosemod/choice:deleteresponsesmod/choice:downloadresponsesmod/choice:readresponsesmod/choice:viewmod/data:addinstancemod/data:approvemod/data:commentmod/data:exportallentriesmod/data:exportentrymod/data:exportownentrymod/data:exportuserinfomod/data:managecommentsmod/data:manageentriesmod/data:managetemplatesmod/data:manageuserpresetsmod/data:ratemod/data:viewmod/data:viewallratingsmod/data:viewalluserpresetsmod/data:viewanyratingmod/data:viewentrymod/data:viewratingmod/data:writeentrymod/feedback:addinstancemod/feedback:completemod/feedback:createprivatetemplatemod/feedback:createpublictemplatemod/feedback:deletesubmissionsmod/feedback:deletetemplatemod/feedback:edititemsmod/feedback:mapcoursemod/feedback:receivemailmod/feedback:viewmod/feedback:viewanalysepagemod/feedback:viewreportsmod/folder:addinstancemod/folder:managefilesmod/folder:viewmod/forum:addinstancemod/forum:addnewsmod/forum:addquestionmod/forum:allowforcesubscribemod/forum:canoverridecutoffmod/forum:canoverridediscussionlockmod/forum:canposttomygroupsmod/forum:cantogglefavouritemod/forum:createattachmentmod/forum:deleteanypostmod/forum:deleteownpostmod/forum:editanypostmod/forum:exportdiscussionmod/forum:exportforummod/forum:exportownpostmod/forum:exportpostmod/forum:grademod/forum:managesubscriptionsmod/forum:movediscussionsmod/forum:pindiscussionsmod/forum:postprivatereplymod/forum:postwithoutthrottlingmod/forum:ratemod/forum:readprivaterepliesmod/forum:replynewsmod/forum:replypostmod/forum:splitdiscussionsmod/forum:startdiscussionmod/forum:viewallratingsmod/forum:viewanyratingmod/forum:viewdiscussionmod/forum:viewhiddentimedpostsmod/forum:viewqandawithoutpostingmod/forum:viewratingmod/forum:viewsubscribersmod/glossary:addinstancemod/glossary:approvemod/glossary:commentmod/glossary:exportmod/glossary:exportentrymod/glossary:exportownentrymod/glossary:importmod/glossary:managecategoriesmod/glossary:managecommentsmod/glossary:manageentriesmod/glossary:ratemod/glossary:viewmod/glossary:viewallratingsmod/glossary:viewanyratingmod/glossary:viewratingmod/glossary:writemod/h5pactivity:addinstancemod/h5pactivity:reviewattemptsmod/h5pactivity:submitmod/h5pactivity:viewmod/imscp:addinstancemod/imscp:viewmod/label:addinstancemod/label:viewmod/lesson:addinstancemod/lesson:editmod/lesson:grademod/lesson:managemod/lesson:manageoverridesmod/lesson:viewmod/lesson:viewreportsmod/lti:addcoursetoolmod/lti:addinstancemod/lti:addmanualinstancemod/lti:addpreconfiguredinstancemod/lti:adminmod/lti:managemod/lti:requesttooladdmod/lti:viewmod/page:addinstancemod/page:viewmod/quiz:addinstancemod/quiz:attemptmod/quiz:deleteattemptsmod/quiz:emailconfirmsubmissionmod/quiz:emailnotifysubmissionmod/quiz:emailwarnoverduemod/quiz:grademod/quiz:ignoretimelimitsmod/quiz:managemod/quiz:manageoverridesmod/quiz:previewmod/quiz:regrademod/quiz:reviewmyattemptsmod/resource:addinstancemod/resource:viewmod/scorm:addinstancemod/scorm:deleteownresponsesmod/scorm:deleteresponsesmod/scorm:savetrackmod/scorm:skipviewmod/scorm:viewreportmod/scorm:viewscoresmod/survey:addinstancemod/survey:downloadmod/survey:participatemod/survey:readresponsesmod/url:addinstancemod/url:viewmod/wiki:addinstancemod/wiki:createpagemod/wiki:editcommentmod/wiki:editpagemod/wiki:managecommentmod/wiki:managefilesmod/wiki:managewikimod/wiki:overridelockmod/wiki:viewcommentmod/wiki:viewpagemod/workshop:addinstancemod/workshop:allocatemod/workshop:deletesubmissionsmod/workshop:editdimensionsmod/workshop:exportsubmissionsmod/workshop:ignoredeadlinesmod/workshop:manageexamplesmod/workshop:overridegradesmod/workshop:peerassessmod/workshop:publishsubmissionsmod/workshop:submitmod/workshop:switchphasemod/workshop:viewmod/workshop:viewallassessmentsmod/workshop:viewallsubmissionsmod/workshop:viewauthornamesmod/workshop:viewauthorpublishedmod/workshop:viewpublishedsubmissionsmod/workshop:viewreviewernamesmoodle/analytics:listinsightsmoodle/analytics:listowninsightsmoodle/analytics:managemodelsmoodle/backup:anonymisemoodle/backup:backupactivitymoodle/backup:backupcoursemoodle/backup:backupsectionmoodle/backup:backuptargetimportmoodle/backup:configuremoodle/backup:downloadfilemoodle/backup:userinfomoodle/badges:awardbadgemoodle/badges:configurecriteriamoodle/badges:configuredetailsmoodle/badges:configuremessagesmoodle/badges:createbadgemoodle/badges:deletebadgemoodle/badges:earnbadgemoodle/badges:manageglobalsettingsmoodle/badges:manageownbadgesmoodle/badges:revokebadgemoodle/badges:viewawardedmoodle/badges:viewbadgesmoodle/badges:viewotherbadgesmoodle/block:editmoodle/block:viewmoodle/blog:createmoodle/blog:manageentriesmoodle/blog:manageexternalmoodle/blog:searchmoodle/blog:viewmoodle/blog:viewdraftsmoodle/calendar:manageentriesmoodle/calendar:managegroupentriesmoodle/calendar:manageownentriesmoodle/category:managemoodle/cohort:assignmoodle/cohort:managemoodle/cohort:viewmoodle/comment:deletemoodle/comment:postmoodle/comment:viewmoodle/competency:competencygrademoodle/competency:competencymanagemoodle/competency:competencyviewmoodle/competency:coursecompetencyconfiguremoodle/competency:coursecompetencygradablemoodle/competency:coursecompetencymanagemoodle/competency:coursecompetencyviewmoodle/competency:evidencedeletemoodle/competency:plancommentmoodle/competency:plancommentownmoodle/competency:planmanagemoodle/competency:planmanagedraftmoodle/competency:planmanageownmoodle/competency:planmanageowndraftmoodle/competency:planrequestreviewmoodle/competency:planrequestreviewownmoodle/competency:planreviewmoodle/competency:planviewmoodle/competency:planviewdraftmoodle/competency:planviewownmoodle/competency:planviewowndraftmoodle/competency:templatemanagemoodle/competency:templateviewmoodle/competency:usercompetencycommentmoodle/competency:usercompetencycommentownmoodle/competency:usercompetencyrequestreviewmoodle/competency:usercompetencyrequestreviewownmoodle/competency:usercompetencyreviewmoodle/competency:usercompetencyviewmoodle/competency:userevidencemanagemoodle/competency:userevidencemanageownmoodle/competency:userevidenceviewmoodle/contentbank:accessmoodle/contentbank:deleteanycontentmoodle/contentbank:deleteowncontentmoodle/contentbank:manageanycontentmoodle/contentbank:manageowncontentmoodle/contentbank:uploadmoodle/contentbank:useeditormoodle/course:activityvisibilitymoodle/course:bulkmessagingmoodle/course:changecategorymoodle/course:changefullnamemoodle/course:changeidnumbermoodle/course:changelockedcustomfieldsmoodle/course:changeshortnamemoodle/course:changesummarymoodle/course:configurecustomfieldsmoodle/course:createmoodle/course:creategroupconversationsmoodle/course:deletemoodle/course:enrolconfigmoodle/course:enrolreviewmoodle/course:ignoreavailabilityrestrictionsmoodle/course:ignorefilesizelimitsmoodle/course:isincompletionreportsmoodle/course:manageactivitiesmoodle/course:managefilesmoodle/course:managegroupsmoodle/course:managescalesmoodle/course:markcompletemoodle/course:movesectionsmoodle/course:overridecompletionmoodle/course:recommendactivitymoodle/course:renamerolesmoodle/course:requestmoodle/course:resetmoodle/course:reviewotherusersmoodle/course:sectionvisibilitymoodle/course:setcurrentsectionmoodle/course:setforcedlanguagemoodle/course:tagmoodle/course:togglecompletionmoodle/course:updatemoodle/course:useremailmoodle/course:viewhiddenactivitiesmoodle/course:viewscalesmoodle/course:viewsuspendedusersmoodle/course:visibilitymoodle/filter:managemoodle/grade:editmoodle/grade:exportmoodle/grade:hidemoodle/grade:importmoodle/grade:lockmoodle/grade:managemoodle/grade:managegradingformsmoodle/grade:managelettersmoodle/grade:manageoutcomesmoodle/grade:managesharedformsmoodle/grade:sharegradingformsmoodle/grade:unlockmoodle/grade:viewmoodle/grade:viewallmoodle/grade:viewhiddenmoodle/h5p:deploymoodle/h5p:setdisplayoptionsmoodle/h5p:updatelibrariesmoodle/my:configsyspagesmoodle/my:manageblocksmoodle/notes:managemoodle/notes:viewmoodle/portfolio:exportmoodle/question:addmoodle/question:configmoodle/question:editallmoodle/question:editminemoodle/question:flagmoodle/question:managecategorymoodle/question:moveallmoodle/question:moveminemoodle/question:tagallmoodle/question:tagminemoodle/question:useallmoodle/question:useminemoodle/question:viewallmoodle/question:viewminemoodle/rating:ratemoodle/rating:viewmoodle/rating:viewallmoodle/rating:viewanymoodle/restore:configuremoodle/restore:createusermoodle/restore:restoreactivitymoodle/restore:restorecoursemoodle/restore:restoresectionmoodle/restore:restoretargetimportmoodle/restore:rolldatesmoodle/restore:uploadfilemoodle/restore:userinfomoodle/restore:viewautomatedfileareamoodle/role:assignmoodle/role:managemoodle/role:overridemoodle/role:reviewmoodle/role:safeoverridemoodle/role:switchrolesmoodle/search:querymoodle/site:approvecoursemoodle/site:configmoodle/site:configviewmoodle/site:deleteanymessagemoodle/site:deleteownmessagemoodle/site:doclinksmoodle/site:forcelanguagemoodle/site:maintenanceaccessmoodle/site:manageallmessagingmoodle/site:manageblocksmoodle/site:managecontextlocksmoodle/site:messageanyusermoodle/site:mnetlogintoremotemoodle/site:readallmessagesmoodle/site:sendmessagemoodle/site:trustcontentmoodle/site:uploadusersmoodle/site:viewanonymouseventsmoodle/site:viewfullnamesmoodle/site:viewparticipantsmoodle/site:viewreportsmoodle/site:viewuseridentitymoodle/tag:editmoodle/tag:editblocksmoodle/tag:flagmoodle/tag:managemoodle/user:changeownpasswordmoodle/user:createmoodle/user:deletemoodle/user:editmessageprofilemoodle/user:editownmessageprofilemoodle/user:editownprofilemoodle/user:editprofilemoodle/user:ignoreuserquotamoodle/user:loginasmoodle/user:manageblocksmoodle/user:manageownblocksmoodle/user:manageownfilesmoodle/user:managesyspagesmoodle/user:readuserblogsmoodle/user:readuserpostsmoodle/user:updatemoodle/user:viewalldetailsmoodle/user:viewlastipmoodle/user:viewuseractivitiesreportmoodle/webservice:managealltokensqtype/lti:addcoursetoolqtype/lti:adddefaultinstanceqtype/lti:addgloballypreconfigedtoolinstanceqtype/lti:addinstanceqtype/lti:adminqtype/lti:backupcourseqtype/lti:manageqtype/lti:regradeltiqtype/lti:requesttooladdqtype/lti:viewquizaccess/seb:manage_filemanager_sebconfigfilequizaccess/seb:manage_seb_activateurlfilteringquizaccess/seb:manage_seb_allowedbrowserexamkeysquizaccess/seb:manage_seb_allowreloadinexamquizaccess/seb:manage_seb_allowspellcheckingquizaccess/seb:manage_seb_allowuserquitsebquizaccess/seb:manage_seb_enableaudiocontrolquizaccess/seb:manage_seb_expressionsallowedquizaccess/seb:manage_seb_expressionsblockedquizaccess/seb:manage_seb_filterembeddedcontentquizaccess/seb:manage_seb_linkquitsebquizaccess/seb:manage_seb_muteonstartupquizaccess/seb:manage_seb_quitpasswordquizaccess/seb:manage_seb_regexallowedquizaccess/seb:manage_seb_regexblockedquizaccess/seb:manage_seb_requiresafeexambrowserquizaccess/seb:manage_seb_showkeyboardlayoutquizaccess/seb:manage_seb_showreloadbuttonquizaccess/seb:manage_seb_showsebdownloadlinkquizaccess/seb:manage_seb_showsebtaskbarquizaccess/seb:manage_seb_showtimequizaccess/seb:manage_seb_showwificontrolquizaccess/seb:manage_seb_templateidquizaccess/seb:manage_seb_userconfirmquitquizaccess/seb:managetemplatesquizaccess/wifiresilience:adminmessagesquizaccess/wifiresilience:browserchecksquizaccess/wifiresilience:inspectresponsesquizaccess/wifiresilience:localresponsesquizaccess/wifiresilience:uploadresponsesquizaccess/wifiresilience:viewlivedevicesquizaccess/wifiresilience:viewtechchecksquiz/grading:viewidnumberquiz/grading:viewstudentnamesquiz/statistics:viewreport/completion:viewreport/customsql:definequeriesreport/customsql:managecategoriesreport/customsql:viewreport/loglive:viewreport/log:viewreport/log:viewtodayreport/outline:viewreport/outline:viewuserreportreport/participation:viewreport/performance:viewreport/progress:viewreport/questioninstances:viewreport/security:viewreport/stats:viewreport/status:viewreport/usersessions:manageownsessionsrepository/areafiles:viewrepository/boxnet:viewrepository/contentbank:accesscoursecategorycontentrepository/contentbank:accesscoursecontentrepository/contentbank:accessgeneralcontentrepository/contentbank:viewrepository/coursefiles:viewrepository/dropbox:viewrepository/equella:viewrepository/filesystem:viewrepository/flickr_public:viewrepository/flickr:viewrepository/googledocs:viewrepository/local:viewrepository/merlot:viewrepository/nextcloud:viewrepository/onedrive:viewrepository/opencast:viewrepository/picasa:viewrepository/recent:viewrepository/s3:viewrepository/skydrive:viewrepository/upload:viewrepository/url:viewrepository/user:viewrepository/webdav:viewrepository/wikimedia:viewrepository/youtube:viewtool/coursedates:setdatestool/customlang:edittool/customlang:viewtool/dataprivacy:downloadallrequeststool/dataprivacy:downloadownrequesttool/dataprivacy:makedatadeletionrequestsforchildrentool/dataprivacy:makedatarequestsforchildrentool/dataprivacy:managedataregistrytool/dataprivacy:managedatarequeststool/dataprivacy:requestdeletetool/dataprivacy:requestdeleteforotherusertool/lpmigrate:frameworksmigratetool/monitor:managerulestool/monitor:managetooltool/monitor:subscribetool/opencast:externalapitool/opencast:instructortool/opencast:learnertool/policy:accepttool/policy:acceptbehalftool/policy:managedocstool/policy:viewacceptancestool/recyclebin:deleteitemstool/recyclebin:restoreitemstool/recyclebin:viewitemstool/uploaduser:uploaduserpicturestool/usertours:managetourswebservice/soap:usewebservice/xmlrpc:usemod/quiz:viewmod/quiz:viewreportsmoodle/category:viewcourselistmoodle/category:viewhiddencategoriesmoodle/course:viewmoodle/course:viewhiddencoursesmoodle/course:viewhiddensectionsmoodle/course:viewhiddenuserfieldsmoodle/course:viewparticipantsmoodle/site:accessallgroupsmoodle/user:viewdetailsmoodle/user:viewhiddendetailsmoodle/webservice:createmobiletokenmoodle/webservice:createtokenquizaccess/seb:bypasssebreport/courseoverview:viewwebservice/rest:use diff --git a/docs/lmssetup.rst b/docs/lmssetup.rst index e29d10c6..9f722aff 100644 --- a/docs/lmssetup.rst +++ b/docs/lmssetup.rst @@ -66,7 +66,7 @@ SEB Server internally. Use the **"Type"** selector to specify the type of the LM Server tries to make use of the described API's of the Moodle system but there is currently no SEB restriction plugin available that works with SEB Server. Note that Moodle integration is implemented partially within SEB Server version 1.1.x. Only the course access feature is implemented and the course restriction feature will come with a future SEB Server release -- **Moodle with SEB Server Plugin**: The `SEB Server Plugin for Moodle `_ is new and supported by SEB Server since version 1.5. +- **Moodle with SEB Server Plugin**: The `SEB Server Plugin for Moodle `_ is new and supported by SEB Server since version 1.5. With this plugin installed on Moodle side, SEB Server is able to more efficiently communicate with Moodle to fetch course data as well as restricting the quiz on Moodle side For SEB only access, using a auto-generated Browser Exam Key (BEK) for SEB restriction. Also the Moodle user name resolving for SEB Server monitoring is less error prone especially if Single Sign On some kind of login provider for Moodle is involved. Furthermore the new SEB Server Plugin for Moodle will be constantly extended and improved with new features in the future. @@ -260,6 +260,6 @@ Install SEB restriction API plugin There is a new SEB Server integration plugin for Moodle available since SEB Server 1.5 that can be used with the LMS Setup type Moodle with SEB Server Plugin. This Plugin supports and improves all common SEB Server LMS binding features such as Course-Access, SEB Restriction and LMS Session Name Resolving. It is also planed to extend and improve this plugin with new Moodle specific feature for further releases of SEB Server. - - `Documentation `_ - - `Repository `_ + - `Documentation `_ + - `Repository `_ diff --git a/docs/monitoring.rst b/docs/monitoring.rst index 554bbbbb..1e868646 100644 --- a/docs/monitoring.rst +++ b/docs/monitoring.rst @@ -108,6 +108,14 @@ In the detail view you are also able to use the instructions "Quit SEB Client" a Optional Live Proctoring ------------------------ +.. attention:: + + Deprecation + + The SEB Server live proctoring integration with Zoom and Jitsi Meet will be deprecated within the next upcoming version of SEB Server 1.6. + + This means live proctoring is still available for dedicated SEB versions, but not actively maintained and supported any more. + Live proctoring is a new and yet experimental feature of SEB and SEB Server. The feature is fully optional and not enabled by default. This section is about the live proctoring on monitoring a running exam and using the optional live proctoring within. To configure the optional live proctoring for a specific exam please have a look at `Optional Live Proctoring `_ diff --git a/docs/requirements.txt b/docs/requirements.txt index eb2a5188..53d44466 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,5 @@ docutils<0.18 sphinx==5.3.0 -sphinx_rtd_theme==1.1.1 +sphinx_rtd_theme==2.0.0 readthedocs-sphinx-search==0.1.1 urllib3==1.26.13 \ No newline at end of file From 29265dd7e1fd857e509e265ba844b78b9845cbdd Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 22 Feb 2024 09:01:15 +0100 Subject: [PATCH 11/31] SEBSERV-469 implementation --- .../gbl/model/sebconfig/SEBClientConfig.java | 21 +++- .../ch/ethz/seb/sebserver/gbl/util/Utils.java | 18 +++ .../content/configs/SEBClientConfigForm.java | 40 ++++--- .../gui/form/SelectionFieldBuilder.java | 2 + .../gui/widget/MultiSelectionCombo.java | 110 ++++++++++-------- .../dao/impl/SEBClientConfigDAOImpl.java | 21 +++- .../sebconfig/ClientConfigService.java | 2 +- .../impl/ClientConfigServiceImpl.java | 2 +- .../session/ExamSessionService.java | 4 +- .../session/impl/ExamSessionServiceImpl.java | 4 +- .../weblayer/api/ExamAPI_V1_Controller.java | 50 +++++--- .../api/SEBClientConfigController.java | 2 +- src/main/resources/messages.properties | 3 + .../gbl/model/ModelObjectJSONGenerator.java | 3 +- .../gui/integration/ClientConfigTest.java | 2 + .../admin/ExamProctoringRoomServiceTest.java | 3 +- 16 files changed, 200 insertions(+), 87 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/SEBClientConfig.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/SEBClientConfig.java index 890fb6a0..6765bf43 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/SEBClientConfig.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/sebconfig/SEBClientConfig.java @@ -11,6 +11,11 @@ package ch.ethz.seb.sebserver.gbl.model.sebconfig; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; +import java.util.Collection; +import java.util.Set; + +import ch.ethz.seb.sebserver.gbl.util.Utils; +import org.apache.commons.lang3.StringUtils; import org.hibernate.validator.constraints.URL; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; @@ -52,6 +57,7 @@ public final class SEBClientConfig implements GrantEntity, Activatable { public static final String ATTR_ENCRYPT_CERTIFICATE_ASYM = "cert_encryption_asym"; public static final String FILTER_ATTR_CREATION_DATE = "creation_date"; + public static final String ATTR_EXAM_SELECTION = "exam_selection"; public enum ConfigPurpose { START_EXAM, @@ -174,6 +180,8 @@ public final class SEBClientConfig implements GrantEntity, Activatable { @JsonProperty(SEB_CLIENT_CONFIGURATION.ATTR_LAST_UPDATE_USER) public final String lastUpdateUser; + @JsonProperty(SEBClientConfig.ATTR_EXAM_SELECTION) + public final Set selectedExams; @JsonCreator public SEBClientConfig( @@ -204,7 +212,8 @@ public final class SEBClientConfig implements GrantEntity, Activatable { @JsonProperty(ATTR_ENCRYPT_CERTIFICATE_ASYM) final Boolean encryptCertificateAsym, @JsonProperty(SEB_CLIENT_CONFIGURATION.ATTR_ACTIVE) final Boolean active, @JsonProperty(SEB_CLIENT_CONFIGURATION.ATTR_LAST_UPDATE_TIME) final DateTime lastUpdateTime, - @JsonProperty(SEB_CLIENT_CONFIGURATION.ATTR_LAST_UPDATE_USER) final String lastUpdateUser) { + @JsonProperty(SEB_CLIENT_CONFIGURATION.ATTR_LAST_UPDATE_USER) final String lastUpdateUser, + @JsonProperty(SEBClientConfig.ATTR_EXAM_SELECTION) final Set selectedExams) { this.id = id; this.institutionId = institutionId; @@ -240,6 +249,7 @@ public final class SEBClientConfig implements GrantEntity, Activatable { this.active = active; this.lastUpdateTime = lastUpdateTime; this.lastUpdateUser = lastUpdateUser; + this.selectedExams = Utils.immutableSetOf(selectedExams); } public SEBClientConfig(final Long institutionId, final POSTMapper postParams) { @@ -281,6 +291,7 @@ public final class SEBClientConfig implements GrantEntity, Activatable { this.active = false; this.lastUpdateTime = postParams.getDateTime(CONFIGURATION_NODE.ATTR_LAST_UPDATE_TIME); this.lastUpdateUser = postParams.getString(CONFIGURATION_NODE.ATTR_LAST_UPDATE_USER); + this.selectedExams = Utils.immutableSetOf(Utils.getIdsFromString(postParams.getString(SEBClientConfig.ATTR_EXAM_SELECTION))); } @Override @@ -424,6 +435,10 @@ public final class SEBClientConfig implements GrantEntity, Activatable { return this.lastUpdateUser; } + public Set getSelectedExams() { + return selectedExams; + } + @Override public String toString() { final StringBuilder builder = new StringBuilder(); @@ -503,7 +518,8 @@ public final class SEBClientConfig implements GrantEntity, Activatable { this.encryptCertificateAsym, this.active, this.lastUpdateTime, - this.lastUpdateUser); + this.lastUpdateUser, + this.selectedExams); } public static SEBClientConfig createNew(final Long institutionId, final long pingIterval) { @@ -533,6 +549,7 @@ public final class SEBClientConfig implements GrantEntity, Activatable { false, false, null, + null, null); } diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/util/Utils.java b/src/main/java/ch/ethz/seb/sebserver/gbl/util/Utils.java index 5f558cdc..26a5a583 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/util/Utils.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/util/Utils.java @@ -935,4 +935,22 @@ public final class Utils { return "Basic " + base64Creds; } + public static Set getIdsFromString(final String idsString) { + if (StringUtils.isBlank(idsString)) { + return Collections.emptySet(); + } + + return Arrays + .stream(StringUtils.split(idsString, Constants.LIST_SEPARATOR_CHAR)) + .map(s -> { + try { + return Long.valueOf(s); + } catch (final Exception e) { + log.warn("Failed to parse String: {} to Long", s); + return null; + } + }) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + } } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/configs/SEBClientConfigForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/configs/SEBClientConfigForm.java index 407e242e..5dbe780b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/configs/SEBClientConfigForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/configs/SEBClientConfigForm.java @@ -134,6 +134,9 @@ public class SEBClientConfigForm implements TemplateComposer { private static final LocTextKey FORM_CONFIRM_ENCRYPT_SECRET_TEXT_KEY = new LocTextKey("sebserver.clientconfig.form.encryptSecret.confirm"); + private static final LocTextKey FORM_EXAM_SELECTION_TEXT_KEY = + new LocTextKey("sebserver.clientconfig.form.examselection"); + private static final LocTextKey DELETE_CONFIRM = new LocTextKey("sebserver.clientconfig.action.delete.confirm"); private static final LocTextKey DELETE_SUCCESS = @@ -409,20 +412,28 @@ public class SEBClientConfigForm implements TemplateComposer { .mandatory(!isReadonly)) .withDefaultSpanEmptyCell(3) + .addField(FormBuilder.multiComboSelection( + SEBClientConfig.ATTR_EXAM_SELECTION, + FORM_EXAM_SELECTION_TEXT_KEY, + StringUtils.join(clientConfig.selectedExams, Constants.LIST_SEPARATOR), + () -> pageService.getResourceService().getExamLogSelectionResources()) + .withInputSpan(5)) + .withDefaultSpanEmptyCell(1); + // VDI - .withDefaultSpanInput(2) - .addFieldIf( - () -> false, // TODO skipped for version 1.2 --> 1.3 or 1.4 - () -> FormBuilder.singleSelection( - SEBClientConfig.ATTR_VDI_TYPE, - VDI_TYPE_TEXT_KEY, - clientConfig.vdiType != null - ? clientConfig.vdiType.name() - : SEBClientConfig.VDIType.NO.name(), - () -> this.pageService.getResourceService().vdiTypeResources()) - .mandatory(!isReadonly)) - .withDefaultSpanEmptyCell(3); +// .withDefaultSpanInput(2) +// .addFieldIf( +// () -> false, // TODO skipped for version 1.2 --> 1.3 or 1.4 +// () -> FormBuilder.singleSelection( +// SEBClientConfig.ATTR_VDI_TYPE, +// VDI_TYPE_TEXT_KEY, +// clientConfig.vdiType != null +// ? clientConfig.vdiType.name() +// : SEBClientConfig.VDIType.NO.name(), +// () -> this.pageService.getResourceService().vdiTypeResources()) +// .mandatory(!isReadonly)) +// .withDefaultSpanEmptyCell(3); // VDI Attributes @@ -460,7 +471,10 @@ public class SEBClientConfigForm implements TemplateComposer { FALLBACK_TEXT_KEY, clientConfig.fallback != null ? clientConfig.fallback.toString() - : Constants.FALSE_STRING)); + : Constants.FALSE_STRING)) + .withDefaultSpanEmptyCell(3) + + ; // Fallback Attributes diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java b/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java index fdb121e4..0b15835c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/form/SelectionFieldBuilder.java @@ -10,6 +10,7 @@ package ch.ethz.seb.sebserver.gui.form; import java.util.Arrays; import java.util.Collection; +import java.util.Comparator; import java.util.List; import java.util.function.Consumer; import java.util.function.Supplier; @@ -122,6 +123,7 @@ public final class SelectionFieldBuilder extends FieldBuilder { this.itemsSupplier.get() .stream() .filter(tuple -> keys.contains(tuple._1)) + .sorted((t1, t2) -> String.CASE_INSENSITIVE_ORDER.compare(t1._2, t2._2)) .map(tuple -> tuple._1) .forEach(v -> buildReadonlyLabel(builder, composite, v, 1)); } diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/widget/MultiSelectionCombo.java b/src/main/java/ch/ethz/seb/sebserver/gui/widget/MultiSelectionCombo.java index 8f7dd457..0df1a8fa 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/widget/MultiSelectionCombo.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/widget/MultiSelectionCombo.java @@ -8,22 +8,17 @@ package ch.ethz.seb.sebserver.gui.widget; -import java.util.ArrayList; -import java.util.Arrays; +import java.util.*; import java.util.List; -import java.util.Optional; +import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import org.apache.commons.lang3.StringUtils; import org.eclipse.rap.rwt.widgets.DropDown; import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Text; +import org.eclipse.swt.widgets.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,13 +28,11 @@ import ch.ethz.seb.sebserver.gui.service.page.PageService; public final class MultiSelectionCombo extends Composite implements Selection { + public static final LocTextKey DESELECT_TOOLTIP = new LocTextKey( "sebserver.form.multiselect.deselect.tooltip" ); + private static final Logger log = LoggerFactory.getLogger(MultiSelectionCombo.class); private static final long serialVersionUID = -7787134114963647332L; - private final WidgetFactory widgetFactory; - - private final List selectionControls = new ArrayList<>(); - private final List> valueMapping = new ArrayList<>(); private final List> availableValues = new ArrayList<>(); private final List> selectedValues = new ArrayList<>(); @@ -50,7 +43,10 @@ public final class MultiSelectionCombo extends Composite implements Selection { private final Composite updateAnchor; private final String testKey; + private final Table selectionTable; + private Listener listener = null; + private WidgetFactory widgetFactory; MultiSelectionCombo( final Composite parent, @@ -78,7 +74,7 @@ public final class MultiSelectionCombo extends Composite implements Selection { this.textInput.addListener(SWT.FocusIn, event -> openDropDown()); this.textInput.addListener(SWT.Modify, event -> openDropDown()); this.textInput.addListener(SWT.MouseUp, event -> openDropDown()); - this.dropDown.addListener(SWT.Selection, event -> { + this.dropDown.addListener(SWT.DefaultSelection, event -> { final int selectionIndex = this.dropDown.getSelectionIndex(); if (selectionIndex >= 0) { final String selectedItem = this.dropDown.getItems()[selectionIndex]; @@ -86,21 +82,29 @@ public final class MultiSelectionCombo extends Composite implements Selection { } }); + selectionTable = widgetFactory.tableLocalized(this, SWT.NONE); + final GridLayout tableLayout = new GridLayout(1, true); + selectionTable.setLayout(tableLayout); + final GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false); + selectionTable.setLayoutData(gridData); + //selectionTable.setToolTipText(); + selectionTable.addListener(SWT.MouseDoubleClick, this::removeComboSelection); + selectionTable.addListener(SWT.Selection, event -> { + selectionTable.setSelection(-1); + }); + selectionTable.setHeaderVisible(false); + selectionTable.setLinesVisible(true); + this.updateAnchor = updateAnchor; } - private void openDropDown() { - final String text = this.textInput.getText(); - if (text == null) { - this.dropDown.setVisible(false); + @Override + public void setToolTipText(final String tooltipText) { + if (tooltipText == null) { + super.setToolTipText(widgetFactory.getI18nSupport().getText(DESELECT_TOOLTIP)); return; } - this.dropDown.setItems(this.availableValues - .stream() - .filter(it -> it._2 != null && it._2.startsWith(text)) - .map(t -> t._2).toArray(String[]::new)); - this.dropDown.setSelectionIndex(0); - this.dropDown.setVisible(true); + super.setToolTipText(tooltipText + "\n\n" + widgetFactory.getI18nSupport().getText(DESELECT_TOOLTIP)); } @Override @@ -157,9 +161,6 @@ public final class MultiSelectionCombo extends Composite implements Selection { @Override public void clear() { this.selectedValues.clear(); - this.selectionControls - .forEach(Control::dispose); - this.selectionControls.clear(); this.availableValues.clear(); this.availableValues.addAll(this.valueMapping); } @@ -170,42 +171,39 @@ public final class MultiSelectionCombo extends Composite implements Selection { } this.selectedValues.add(item); - final Label label = this.widgetFactory.label(this, item._2); - label.setData(OPTION_VALUE, item._2); - final GridData textCell = new GridData(SWT.LEFT, SWT.CENTER, true, true); - label.setLayoutData(textCell); - label.addListener(SWT.MouseDoubleClick, this::removeComboSelection); - this.selectionControls.add(label); - WidgetFactory.setARIALabel(label, item._2); - WidgetFactory.setTestId(label, (this.testKey != null) ? this.testKey + "_" + item._1 : item._1); + sortSelectedTable(); this.availableValues.remove(item); PageService.updateScrolledComposite(this); this.updateAnchor.layout(true, true); } + private void sortSelectedTable() { + selectionTable.removeAll(); + selectedValues.sort((t1, t2) -> String.CASE_INSENSITIVE_ORDER.compare(t1._2, t2._2)); + selectedValues.stream().forEach(t -> { + final TableItem tItem = new TableItem(selectionTable, SWT.NONE); + tItem.setText(0, t._2); + tItem.setData("tuple", t); + WidgetFactory.setARIALabel(tItem, t._2); + WidgetFactory.setTestId(tItem, (this.testKey != null) ? this.testKey + "_" + t._1 : t._1); + }); + } + private void removeComboSelection(final Event event) { if (event.widget == null) { return; } - final String selectionKey = (String) event.widget.getData(OPTION_VALUE); - final Optional findFirst = this.selectionControls.stream() - .filter(t -> selectionKey.equals(t.getData(OPTION_VALUE))) - .findFirst(); - if (!findFirst.isPresent()) { - return; - } - - final Control control = findFirst.get(); - final int indexOf = this.selectionControls.indexOf(control); - this.selectionControls.remove(control); - control.dispose(); - - final Tuple value = this.selectedValues.remove(indexOf); + final TableItem item = selectionTable.getItem(new Point(event.x, event.y)); + @SuppressWarnings("unchecked") + final Tuple value = (Tuple) item.getData("tuple"); + this.selectedValues.remove(value); this.availableValues.add(value); + sortSelectedTable(); + PageService.updateScrolledComposite(this); this.updateAnchor.layout(true, true); if (this.listener != null) { @@ -238,4 +236,18 @@ public final class MultiSelectionCombo extends Composite implements Selection { return findFirst.orElse(null); } + private void openDropDown() { + final String text = this.textInput.getText(); + if (text == null) { + this.dropDown.setVisible(false); + return; + } + this.dropDown.setItems(this.availableValues + .stream() + .filter(it -> it._2 != null && it._2.startsWith(text)) + .map(t -> t._2).toArray(String[]::new)); + this.dropDown.setSelectionIndex(0); + this.dropDown.setVisible(true); + } + } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/SEBClientConfigDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/SEBClientConfigDAOImpl.java index 428e4756..6d708415 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/SEBClientConfigDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/SEBClientConfigDAOImpl.java @@ -489,7 +489,11 @@ public class SEBClientConfigDAOImpl implements SEBClientConfigDAO { additionalAttributes.containsKey(SEBClientConfig.ATTR_ENCRYPT_CERTIFICATE_ASYM), BooleanUtils.toBooleanObject(record.getActive()), Utils.toDateTimeUTC(record.getLastUpdateTime()), - record.getLastUpdateUser())); + record.getLastUpdateUser(), + Utils.getIdsFromString( + additionalAttributes.containsKey(SEBClientConfig.ATTR_EXAM_SELECTION) + ? additionalAttributes.get(SEBClientConfig.ATTR_EXAM_SELECTION).getValue() + : null))); } private String getEncryptionPassword(final SEBClientConfig sebClientConfig) { @@ -685,6 +689,21 @@ public class SEBClientConfigDAOImpl implements SEBClientConfigDAO { configId, SEBClientConfig.ATTR_ENCRYPT_CERTIFICATE_ASYM); } + + final Set selectedExams = sebClientConfig.getSelectedExams(); + if (selectedExams != null && !selectedExams.isEmpty()) { + final String ids = StringUtils.join(selectedExams, Constants.LIST_SEPARATOR); + this.additionalAttributesDAO.saveAdditionalAttribute( + EntityType.SEB_CLIENT_CONFIGURATION, + configId, + SEBClientConfig.ATTR_EXAM_SELECTION, + ids); + } else { + this.additionalAttributesDAO.delete( + EntityType.SEB_CLIENT_CONFIGURATION, + configId, + SEBClientConfig.ATTR_EXAM_SELECTION); + } } private Long disposeSEBClientConfig(final Long pk) { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/ClientConfigService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/ClientConfigService.java index 3ebd907d..206393a5 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/ClientConfigService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/ClientConfigService.java @@ -63,5 +63,5 @@ public interface ClientConfigService { boolean checkAccess(SEBClientConfig config); @Async(AsyncServiceSpringConfig.EXECUTOR_BEAN_NAME) - void initalCheckAccess(SEBClientConfig config); + void initialCheckAccess(SEBClientConfig config); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ClientConfigServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ClientConfigServiceImpl.java index 06f25b7c..034b7db5 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ClientConfigServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/ClientConfigServiceImpl.java @@ -504,7 +504,7 @@ public class ClientConfigServiceImpl implements ClientConfigService { } @Override - public void initalCheckAccess(final SEBClientConfig config) { + public void initialCheckAccess(final SEBClientConfig config) { checkAccess(config); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/ExamSessionService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/ExamSessionService.java index 602f3e0d..fa41d80c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/ExamSessionService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/ExamSessionService.java @@ -9,6 +9,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.session; import java.io.OutputStream; +import java.security.Principal; import java.util.Collection; import java.util.Set; import java.util.function.Predicate; @@ -130,9 +131,10 @@ public interface ExamSessionService { /** Gets all currently running Exams for a particular Institution. * * @param institutionId the Institution identifier + * @param examSelectionFilter Exam selection filter from SEB connection configuration * @return Result referencing the list of all currently running Exams of the institution or to an error if * happened. */ - Result> getRunningExamsForInstitution(Long institutionId); + Result> getRunningExams(Long institutionId, Predicate examSelectionFilter); /** Gets all currently running Exams for a particular FilterMap. * diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionServiceImpl.java index 87c3cc79..bae50e67 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionServiceImpl.java @@ -10,6 +10,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl; import java.io.IOException; import java.io.OutputStream; +import java.security.Principal; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -251,9 +252,10 @@ public class ExamSessionServiceImpl implements ExamSessionService { } @Override - public Result> getRunningExamsForInstitution(final Long institutionId) { + public Result> getRunningExams(final Long institutionId, final Predicate examSelectionFilter) { return this.examDAO.allIdsOfRunning(institutionId) .map(col -> col.stream() + .filter(examSelectionFilter) .map(this::getRunningExam) .filter(Result::hasValue) .map(Result::get) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAPI_V1_Controller.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAPI_V1_Controller.java index 9b37dc09..2f35228a 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAPI_V1_Controller.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAPI_V1_Controller.java @@ -11,17 +11,17 @@ package ch.ethz.seb.sebserver.webservice.weblayer.api; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.security.Principal; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Objects; +import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import java.util.function.Predicate; import java.util.stream.Collectors; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import ch.ethz.seb.sebserver.gbl.model.sebconfig.SEBClientConfig; +import ch.ethz.seb.sebserver.gbl.util.Utils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -132,7 +132,10 @@ public class ExamAPI_V1_Controller { // Crate list of running exams final List result; if (examId == null) { - result = this.examSessionService.getRunningExamsForInstitution(institutionId) + + result = this.examSessionService.getRunningExams( + institutionId, + getExamSelectionPredicate(principal.getName())) .getOrThrow() .stream() .map(this::createRunningExamInfo) @@ -161,17 +164,7 @@ public class ExamAPI_V1_Controller { this.executor); } - private boolean checkConsistency(final RunningExamInfo info) { - if (StringUtils.isNotBlank(info.name) && - StringUtils.isNotBlank(info.url) && - StringUtils.isNotBlank(info.examId)) { - return true; - } - - log.warn("Invalid running exam detected. Filter out exam : {}", info); - return false; - } @RequestMapping( path = API.EXAM_API_HANDSHAKE_ENDPOINT, @@ -420,4 +413,31 @@ public class ExamAPI_V1_Controller { .onSuccess(bek -> response.setHeader(API.EXAM_API_EXAM_ALT_BEK, bek)); } + private Predicate getExamSelectionPredicate(final String clientName) { + return this.sebClientConfigDAO + .byClientName(clientName) + .map(this::getExamSelectionPredicate) + .onError(error -> log.warn("Failed to get SEB connection configuration by name: {}", clientName)) + .getOr(Utils.truePredicate()); + } + + private Predicate getExamSelectionPredicate(final SEBClientConfig config) { + if (config == null || config.selectedExams.isEmpty()) { + return Utils.truePredicate(); + } + return config.getSelectedExams()::contains; + } + + private boolean checkConsistency(final RunningExamInfo info) { + if (StringUtils.isNotBlank(info.name) && + StringUtils.isNotBlank(info.url) && + StringUtils.isNotBlank(info.examId)) { + + return true; + } + + log.warn("Invalid running exam detected. Filter out exam : {}", info); + return false; + } + } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/SEBClientConfigController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/SEBClientConfigController.java index 3aac116f..58931d96 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/SEBClientConfigController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/SEBClientConfigController.java @@ -182,7 +182,7 @@ public class SEBClientConfigController extends ActivatableEntityController notifySaved(final SEBClientConfig entity) { if (entity.isActive()) { // try to get access token for SEB client - this.sebClientConfigService.initalCheckAccess(entity); + this.sebClientConfigService.initialCheckAccess(entity); } return super.notifySaved(entity); } diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 4ceb7c7f..66219338 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -129,6 +129,7 @@ sebserver.form.mandatory.label={0} mandatory sebserver.form.confirm.label=confirm {0} sebserver.form.tablefilter.label={0} table-column filter sebserver.table.column.sort.default.tooltip=Click on the column header to sort the table within this column +sebserver.form.multiselect.deselect.tooltip=Please use double-click to deselect selected items. sebserver.dialog.confirm.deactivation=Note that there are {0} other entities that belong to this entity.
Those will also be deactivated by deactivating this entity.

Are you sure to deactivate this entity? sebserver.dialog.confirm.deactivation.noDependencies=Are you sure you want to deactivate? @@ -1033,6 +1034,8 @@ sebserver.clientconfig.form.certificate=Encrypt with Certificate sebserver.clientconfig.form.certificate.tooltip=Choose identity certificate to be used for encrypting the connection configuration sebserver.clientconfig.form.type.async=Use asymmetric-only encryption sebserver.clientconfig.form.type.async.tooltip=Use old asymmetric-only encryption (for SEB < 2.2) +sebserver.clientconfig.form.examselection=Exams +sebserver.clientconfig.form.examselection.tooltip=List of Exams selected to work with this Connection Configuration. sebserver.clientconfig.form.credentials.title=Client Credentials of Connection Configuration sebserver.clientconfig.form.credentials.info=A SEB client that loads this connection configuration
uses the following credentials to securely connect to the SEB Server. diff --git a/src/test/java/ch/ethz/seb/sebserver/gbl/model/ModelObjectJSONGenerator.java b/src/test/java/ch/ethz/seb/sebserver/gbl/model/ModelObjectJSONGenerator.java index e2f50695..91244bf7 100644 --- a/src/test/java/ch/ethz/seb/sebserver/gbl/model/ModelObjectJSONGenerator.java +++ b/src/test/java/ch/ethz/seb/sebserver/gbl/model/ModelObjectJSONGenerator.java @@ -138,7 +138,8 @@ public class ModelObjectJSONGenerator { false, true, DateTime.now(), - "user123"); + "user123", + null); System.out.println(domainObject.getClass().getSimpleName() + ":"); System.out.println(writerWithDefaultPrettyPrinter.writeValueAsString(domainObject)); diff --git a/src/test/java/ch/ethz/seb/sebserver/gui/integration/ClientConfigTest.java b/src/test/java/ch/ethz/seb/sebserver/gui/integration/ClientConfigTest.java index f5aabb5a..3266b133 100644 --- a/src/test/java/ch/ethz/seb/sebserver/gui/integration/ClientConfigTest.java +++ b/src/test/java/ch/ethz/seb/sebserver/gui/integration/ClientConfigTest.java @@ -128,6 +128,7 @@ public class ClientConfigTest extends GuiIntegrationTest { false, null, null, + null, null)) .call(); @@ -161,6 +162,7 @@ public class ClientConfigTest extends GuiIntegrationTest { false, null, null, + null, null)) .call() .getOrThrow(); diff --git a/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/admin/ExamProctoringRoomServiceTest.java b/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/admin/ExamProctoringRoomServiceTest.java index 493bc12f..34a7f68c 100644 --- a/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/admin/ExamProctoringRoomServiceTest.java +++ b/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/admin/ExamProctoringRoomServiceTest.java @@ -12,6 +12,7 @@ import static org.junit.Assert.*; import java.util.Collection; +import ch.ethz.seb.sebserver.gbl.util.Utils; import org.junit.Before; import org.junit.Test; import org.junit.jupiter.api.Order; @@ -61,7 +62,7 @@ public class ExamProctoringRoomServiceTest extends AdministrationAPIIntegrationT @Order(1) public void test01_checkExamRunning() { final Result> runningExamsForInstitution = - this.examSessionService.getRunningExamsForInstitution(1L); + this.examSessionService.getRunningExams(1L, Utils.truePredicate()); assertFalse(runningExamsForInstitution.hasError()); final Collection collection = runningExamsForInstitution.get(); assertFalse(collection.isEmpty()); From 979d4a6e892f108e3ec26705fd103e7630f5761e Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 22 Feb 2024 13:45:29 +0100 Subject: [PATCH 12/31] SEBSERV-459 implementation --- .../gbl/model/user/UserFeatures.java | 4 ++++ .../seb/sebserver/gui/content/LoginPage.java | 5 +++-- .../sebserver/gui/content/RegisterPage.java | 7 +++++- .../sebserver/webservice/WebserviceInfo.java | 4 ++-- .../weblayer/api/RegisterUserController.java | 22 ++++++++++++++----- .../config/application-ws.properties | 3 +++ src/main/resources/messages.properties | 1 + 7 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserFeatures.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserFeatures.java index 4f5cc0aa..cd95dbbd 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserFeatures.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserFeatures.java @@ -17,8 +17,12 @@ public class UserFeatures { public enum Feature { ADMIN_INSTITUTION("admin.institution"), + + ADMIN_USER_ADMINISTRATION("admin.user.administration"), ADMIN_USER_ACCOUNT("admin.user.account"), + ADMIN_USER_ACCOUNT_SELF_REGISTERING("admin.user.account.self.registering"), + ADMIN_USER_ACCOUNT_SELF_REGISTERING_AUTO_ACTIVATION("admin.user.account.self.registering.autoactivation"), ADMIN_AUDIT_LOGS("admin.auditlogs"), CONFIG_CONNECTION_CONFIGURATION("config.connection.configuration"), diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/LoginPage.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/LoginPage.java index ff99a662..240224d3 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/LoginPage.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/LoginPage.java @@ -59,14 +59,15 @@ public class LoginPage implements TemplateComposer { public LoginPage( final PageService pageService, final DefaultRegisterPage defaultRegisterPage, - @Value("${sebserver.gui.registering:false}") final Boolean registeringEnabled) { + @Value("${sebserver.gui.registering:false}") final boolean guiRegEnabled, + @Value("${sebserver.feature.admin.user.account.self.registering:true}") final boolean webRegEnabled) { this.pageService = pageService; this.authorizationContextHolder = pageService.getAuthorizationContextHolder(); this.widgetFactory = pageService.getWidgetFactory(); this.i18nSupport = pageService.getI18nSupport(); this.defaultRegisterPage = defaultRegisterPage; - this.registeringEnabled = BooleanUtils.toBoolean(registeringEnabled); + this.registeringEnabled = webRegEnabled && guiRegEnabled; } @Override diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/RegisterPage.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/RegisterPage.java index 48f0c3e5..ea498070 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/RegisterPage.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/RegisterPage.java @@ -85,6 +85,9 @@ public class RegisterPage implements TemplateComposer { static final LocTextKey MESSAGE_SUCCESS_TEXT = new LocTextKey("sebserver.login.register.success"); + static final LocTextKey MESSAGE_SUCCESS_ACTIVATION_TEXT = + new LocTextKey("sebserver.login.register.success.activate"); + private final PageService pageService; private final ResourceService resourceService; private final WidgetFactory widgetFactory; @@ -247,7 +250,9 @@ public class RegisterPage implements TemplateComposer { } pageContext.forwardToLoginPage(); - pageContext.publishPageMessage(MESSAGE_SUCCESS_TILE, MESSAGE_SUCCESS_TEXT); + pageContext.publishPageMessage( + MESSAGE_SUCCESS_TILE, + (result.get().active) ? MESSAGE_SUCCESS_TEXT : MESSAGE_SUCCESS_ACTIVATION_TEXT); }); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInfo.java b/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInfo.java index 55756f20..0c43db48 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInfo.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInfo.java @@ -178,10 +178,10 @@ public class WebserviceInfo { } public Map configuredFeatures() { - return Arrays.stream(UserFeatures.Feature.values()).collect(Collectors.toMap( + return new TreeMap<>( Arrays.stream(UserFeatures.Feature.values()).collect(Collectors.toMap( f -> f.featureName, featureService::isEnabledByConfig - )); + ))); } public boolean isMaster() { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/RegisterUserController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/RegisterUserController.java index 41191719..677630c8 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/RegisterUserController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/RegisterUserController.java @@ -10,10 +10,15 @@ package ch.ethz.seb.sebserver.webservice.weblayer.api; import java.util.ArrayList; import java.util.Collection; +import java.util.Map; import javax.servlet.http.HttpServletRequest; +import ch.ethz.seb.sebserver.gbl.model.user.*; +import ch.ethz.seb.sebserver.webservice.WebserviceInfo; +import org.apache.commons.lang3.BooleanUtils; import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.http.MediaType; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.util.MultiValueMap; @@ -30,10 +35,6 @@ import ch.ethz.seb.sebserver.gbl.api.APIMessage.APIMessageException; import ch.ethz.seb.sebserver.gbl.api.POSTMapper; import ch.ethz.seb.sebserver.gbl.api.TooManyRequests; import ch.ethz.seb.sebserver.gbl.model.Domain.USER_ROLE; -import ch.ethz.seb.sebserver.gbl.model.user.PasswordChange; -import ch.ethz.seb.sebserver.gbl.model.user.UserInfo; -import ch.ethz.seb.sebserver.gbl.model.user.UserMod; -import ch.ethz.seb.sebserver.gbl.model.user.UserRole; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.InstitutionDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO; @@ -51,6 +52,8 @@ public class RegisterUserController { private final BeanValidationService beanValidationService; private final LocalBucket requestRateLimitBucket; private final LocalBucket createRateLimitBucket; + private final boolean registeringEnabled; + private final boolean autoActivation; protected RegisterUserController( final InstitutionDAO institutionDAO, @@ -58,12 +61,15 @@ public class RegisterUserController { final UserDAO userDAO, final BeanValidationService beanValidationService, final RateLimitService rateLimitService, + final WebserviceInfo webserviceInfo, @Qualifier(WebSecurityConfig.USER_PASSWORD_ENCODER_BEAN_NAME) final PasswordEncoder userPasswordEncoder) { + final Map features = webserviceInfo.configuredFeatures(); this.userActivityLogDAO = userActivityLogDAO; this.userDAO = userDAO; this.beanValidationService = beanValidationService; - + this. registeringEnabled = BooleanUtils.isTrue(features.get(UserFeatures.Feature.ADMIN_USER_ACCOUNT_SELF_REGISTERING.featureName)); + this.autoActivation = BooleanUtils.isTrue(features.get(UserFeatures.Feature.ADMIN_USER_ACCOUNT_SELF_REGISTERING_AUTO_ACTIVATION.featureName)); this.requestRateLimitBucket = rateLimitService.createRequestLimitBucker(); this.createRateLimitBucket = rateLimitService.createCreationLimitBucker(); } @@ -76,6 +82,10 @@ public class RegisterUserController { @RequestParam final MultiValueMap allRequestParams, final HttpServletRequest request) { + if (!registeringEnabled) { + throw new RuntimeException("Registering is not enabled from backend!"); + } + if (!this.requestRateLimitBucket.tryConsume(1)) { throw new TooManyRequests(); } @@ -107,7 +117,7 @@ public class RegisterUserController { return userAccount; }) .flatMap(this.userDAO::createNew) - .flatMap(account -> this.userDAO.setActive(account, true)) + .flatMap(account -> this.userDAO.setActive(account, autoActivation)) .flatMap(this.userActivityLogDAO::logRegisterAccount) .flatMap(account -> this.userDAO.byModelId(account.getModelId())) .getOrThrow(); diff --git a/src/main/resources/config/application-ws.properties b/src/main/resources/config/application-ws.properties index f7eb7c57..e5968a60 100644 --- a/src/main/resources/config/application-ws.properties +++ b/src/main/resources/config/application-ws.properties @@ -95,6 +95,9 @@ sebserver.webservice.configtemplate.examconfig.default.description=This has auto # features sebserver.feature.admin.institution.enabled=true +sebserver.feature.admin.user.account.self.registering.enabled=true +sebserver.feature.admin.user.account.self.registering.autoactivation.enabled=true + sebserver.feature.seb.liveProctoring.enabled=true sebserver.feature.lms.type.MOCKUP.enabled=true sebserver.feature.exam.noLMS.enabled=true diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 66219338..0e725a13 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -163,6 +163,7 @@ sebserver.login.register=Register sebserver.login.register.form.title=Create an Account sebserver.login.register.do=Create Account sebserver.login.register.success=New account successfully created.
Please log in with your username and password. +sebserver.login.register.success.activate=New account successfully created.
Please contact your system administrator for account activation. ################################ From 684da72060f47fe3f5d92dae98cc3d4b34a4fd3e Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 22 Feb 2024 14:27:57 +0100 Subject: [PATCH 13/31] fixed gui only profile annotations --- .../sebserver/webservice/weblayer/oauth/PreAuthProvider.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/oauth/PreAuthProvider.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/oauth/PreAuthProvider.java index 2aed9dbe..ed561890 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/oauth/PreAuthProvider.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/oauth/PreAuthProvider.java @@ -10,12 +10,16 @@ package ch.ethz.seb.sebserver.webservice.weblayer.oauth; import javax.annotation.PostConstruct; +import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; +import org.springframework.context.annotation.Lazy; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider; import org.springframework.stereotype.Component; import ch.ethz.seb.sebserver.webservice.weblayer.WebServiceUserDetails; +@Lazy @Component +@WebServiceProfile public class PreAuthProvider extends PreAuthenticatedAuthenticationProvider { private final WebServiceUserDetails webServiceUserDetails; From d100a50e1eae211fd32cbb2e60d0ec8bf001c7ad Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 22 Feb 2024 15:02:07 +0100 Subject: [PATCH 14/31] fixed sps bundle and feature keys --- .../seb/sebserver/webservice/WebserviceInfo.java | 14 +++++++------- .../resources/config/application-dev-ws.properties | 10 +++++----- .../resources/config/application-ws.properties | 14 +++++++------- src/test/resources/application-test.properties | 6 +++--- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInfo.java b/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInfo.java index 0c43db48..115cb625 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInfo.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInfo.java @@ -156,21 +156,21 @@ public class WebserviceInfo { } final boolean spsEnabled = BooleanUtils.toBoolean(environment.getProperty( - "sebserver.feature.seb.screenProctoring.enabled", + "sebserver.feature.exam.seb.screenProctoring.enabled", Constants.FALSE_STRING)); final boolean spsBundled = BooleanUtils.toBoolean(environment.getProperty( - "sebserver.feature.seb.screenProctoring.bundled", + "sebserver.feature.exam.seb.screenProctoring.bundled", Constants.FALSE_STRING)); if (spsEnabled && spsBundled) { this.screenProctoringServiceBundle = new ScreenProctoringServiceBundle( - environment.getProperty("sebserver.feature.seb.screenProctoring.bundled.url"), - environment.getProperty("sebserver.feature.seb.screenProctoring.bundled.clientId"), + environment.getProperty("sebserver.feature.exam.seb.screenProctoring.bundled.url"), + environment.getProperty("sebserver.feature.exam.seb.screenProctoring.bundled.clientId"), cryptor.encrypt( - environment.getProperty("sebserver.feature.seb.screenProctoring.bundled.clientPassword")) + environment.getProperty("sebserver.feature.exam.seb.screenProctoring.bundled.clientPassword")) .getOrThrow(), - environment.getProperty("sebserver.feature.seb.screenProctoring.bundled.sebserveraccount.username"), + environment.getProperty("sebserver.feature.exam.seb.screenProctoring.bundled.sebserveraccount.username"), cryptor.encrypt(environment - .getProperty("sebserver.feature.seb.screenProctoring.bundled.sebserveraccount.password")) + .getProperty("sebserver.feature.exam.seb.screenProctoring.bundled.sebserveraccount.password")) .getOrThrow()); } else { this.screenProctoringServiceBundle = new ScreenProctoringServiceBundle(); diff --git a/src/main/resources/config/application-dev-ws.properties b/src/main/resources/config/application-dev-ws.properties index 9f9e5f2b..750f47a7 100644 --- a/src/main/resources/config/application-dev-ws.properties +++ b/src/main/resources/config/application-dev-ws.properties @@ -72,11 +72,11 @@ springdoc.swagger-ui.oauth.clientSecret=${sebserver.password} springdoc.paths-to-exclude=/exam-api,/exam-api/discovery,/sebserver/error,/sebserver/check,/oauth,/exam-api/v1/* # features -sebserver.feature.seb.screenProctoring.enabled=true -sebserver.feature.seb.screenProctoring.bundled=true -sebserver.feature.seb.screenProctoring.bundled.url=http://localhost:8090 -sebserver.feature.seb.screenProctoring.bundled.clientId=sebserverClient -sebserver.feature.seb.screenProctoring.bundled.sebserveraccount.username=SEBServerAPIAccount +sebserver.feature.exam.seb.screenProctoring.enabled=true +sebserver.feature.exam.seb.screenProctoring.bundled=true +sebserver.feature.exam.seb.screenProctoring.bundled.url=http://localhost:8090 +sebserver.feature.exam.seb.screenProctoring.bundled.clientId=sebserverClient +sebserver.feature.exam.seb.screenProctoring.bundled.sebserveraccount.username=SEBServerAPIAccount #sebserver.feature.admin.user.administration.enabled=false #sebserver.feature.admin.user.account.enabled=false diff --git a/src/main/resources/config/application-ws.properties b/src/main/resources/config/application-ws.properties index e5968a60..960ab45a 100644 --- a/src/main/resources/config/application-ws.properties +++ b/src/main/resources/config/application-ws.properties @@ -102,11 +102,11 @@ sebserver.feature.seb.liveProctoring.enabled=true sebserver.feature.lms.type.MOCKUP.enabled=true sebserver.feature.exam.noLMS.enabled=true -sebserver.feature.seb.screenProctoring.enabled=false -sebserver.feature.seb.screenProctoring.bundled=true -sebserver.feature.seb.screenProctoring.bundled.url=sps-service:8090 -sebserver.feature.seb.screenProctoring.bundled.clientId=sebserverClient -sebserver.feature.seb.screenProctoring.bundled.clientPassword=${sps.sebserver.client.secret} -sebserver.feature.seb.screenProctoring.bundled.sebserveraccount.username=SEBServerAPIAccount -sebserver.feature.seb.screenProctoring.bundled.sebserveraccount.password=${sps.sebserver.password} +sebserver.feature.exam.seb.screenProctoring.enabled=false +sebserver.feature.exam.seb.screenProctoring.bundled=true +sebserver.feature.exam.seb.screenProctoring.bundled.url=sps-service:8090 +sebserver.feature.exam.seb.screenProctoring.bundled.clientId=sebserverClient +sebserver.feature.exam.seb.screenProctoring.bundled.clientPassword=${sps.sebserver.client.secret} +sebserver.feature.exam.seb.screenProctoring.bundled.sebserveraccount.username=SEBServerAPIAccount +sebserver.feature.exam.seb.screenProctoring.bundled.sebserveraccount.password=${sps.sebserver.password} diff --git a/src/test/resources/application-test.properties b/src/test/resources/application-test.properties index ab8a6782..2747dec0 100644 --- a/src/test/resources/application-test.properties +++ b/src/test/resources/application-test.properties @@ -45,7 +45,7 @@ management.endpoints.web.base-path=/actuator sebserver.webservice.api.exam.indicator.name=Ping sebserver.webservice.api.exam.indicator.type=LAST_PING sebserver.webservice.api.exam.indicator.color=b4b4b4 -sebserver.webservice.api.exam.indicator.thresholds=[{"value":5000.0,"color":"22b14c"},{"value":10000.0,"color":"ff7e00"},{"value":15000.0,"color":"ed1c24"}] +sebserver.webservice.api.exam.indicator.thresholds=[{"value":5000.0,"color":"22b14c"},{"value":10000.0,"color":"ff7e00"},{"value":15000.0,"color":"ed1c24"}] sebserver.webservice.master.delay.threshold=1000 - -sebserver.feature.seb.screenProctoring.bundled=false \ No newline at end of file + +sebserver.feature.exam.seb.screenProctoring.bundled=false \ No newline at end of file From 4ceaf50385aa4f659013b1ab878d000f1d63b763 Mon Sep 17 00:00:00 2001 From: anhefti Date: Tue, 27 Feb 2024 16:12:32 +0100 Subject: [PATCH 15/31] SEBSERV-408 --- .../seb/sebserver/gui/content/LoginPage.java | 3 +- .../gui/content/exam/ExamFormConfigs.java | 16 +++++++-- .../content/exam/ExamToConfigBindingForm.java | 36 ++++++++++++------- .../dao/impl/ExamConfigurationMapDAOImpl.java | 20 ++++++----- .../ExamConfigurationMappingController.java | 7 +++- 5 files changed, 57 insertions(+), 25 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/LoginPage.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/LoginPage.java index 240224d3..82cdd89b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/LoginPage.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/LoginPage.java @@ -60,6 +60,7 @@ public class LoginPage implements TemplateComposer { final PageService pageService, final DefaultRegisterPage defaultRegisterPage, @Value("${sebserver.gui.registering:false}") final boolean guiRegEnabled, + @Value("${sebserver.gui.self-registering:false}") final boolean guiRegEnabledOld, @Value("${sebserver.feature.admin.user.account.self.registering:true}") final boolean webRegEnabled) { this.pageService = pageService; @@ -67,7 +68,7 @@ public class LoginPage implements TemplateComposer { this.widgetFactory = pageService.getWidgetFactory(); this.i18nSupport = pageService.getI18nSupport(); this.defaultRegisterPage = defaultRegisterPage; - this.registeringEnabled = webRegEnabled && guiRegEnabled; + this.registeringEnabled = webRegEnabled && (guiRegEnabled || guiRegEnabledOld); } @Override diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamFormConfigs.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamFormConfigs.java index c13d387f..51a62228 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamFormConfigs.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamFormConfigs.java @@ -137,6 +137,7 @@ public class ExamFormConfigs implements TemplateComposer { .withSelectionListener(this.pageService.getSelectionPublisher( pageContext, + ActionDefinition.EXAM_CONFIGURATION_MODIFY_FROM_LIST, ActionDefinition.EXAM_CONFIGURATION_EXAM_CONFIG_VIEW_PROP, ActionDefinition.EXAM_CONFIGURATION_DELETE_FROM_LIST, ActionDefinition.EXAM_CONFIGURATION_EXPORT, @@ -144,7 +145,7 @@ public class ExamFormConfigs implements TemplateComposer { .compose(pageContext.copyOf(content)); - final EntityKey configMapKey = (configurationTable.hasAnyContent()) + final EntityKey configKey = (configurationTable.hasAnyContent()) ? new EntityKey( configurationTable.getFirstRowData().configurationNodeId, EntityType.CONFIGURATION_NODE) @@ -162,9 +163,18 @@ public class ExamFormConfigs implements TemplateComposer { .noEventPropagation() .publishIf(() -> examConfigEnabled && editable && !configurationTable.hasAnyContent()) + .newAction(ActionDefinition.EXAM_CONFIGURATION_MODIFY_FROM_LIST) + .withParentEntityKey(entityKey) + .withSelect( + getConfigMappingSelection(configurationTable), + this.examToConfigBindingForm.bindFunction(), + CONFIG_EMPTY_SELECTION_TEXT_KEY) + .noEventPropagation() + .publishIf(() -> examConfigEnabled && editable && configurationTable.hasAnyContent(), false) + .newAction(ActionDefinition.EXAM_CONFIGURATION_EXAM_CONFIG_VIEW_PROP) .withParentEntityKey(entityKey) - .withEntityKey(configMapKey) + .withEntityKey(configKey) .publishIf(() -> examConfigEnabled && readGrant && configurationTable.hasAnyContent(), false) .newAction(ActionDefinition.EXAM_CONFIGURATION_DELETE_FROM_LIST) @@ -179,7 +189,7 @@ public class ExamFormConfigs implements TemplateComposer { } return null; }) - .publishIf(() -> examConfigEnabled && editable && configurationTable.hasAnyContent() && editable, false) + .publishIf(() -> examConfigEnabled && editable && configurationTable.hasAnyContent(), false) .newAction(ActionDefinition.EXAM_CONFIGURATION_GET_CONFIG_KEY) .withSelect( diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamToConfigBindingForm.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamToConfigBindingForm.java index 6c017e24..8aefad2d 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamToConfigBindingForm.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamToConfigBindingForm.java @@ -82,7 +82,7 @@ public class ExamToConfigBindingForm { return action -> { final PageContext pageContext = action.pageContext(); - final EntityKey entityKey = pageContext.getEntityKey(); + final EntityKey entityKey = action.getSingleSelection(); final boolean isNew = entityKey == null; if (isNew) { @@ -103,11 +103,12 @@ public class ExamToConfigBindingForm { final BindFormContext bindFormContext = new BindFormContext( this.pageService, - action.pageContext()); + action.pageContext() + .withEntityKey(entityKey)); final Predicate> doBind = formHandle -> doCreate( this.pageService, - pageContext, + bindFormContext.pageContext, formHandle); // the default page layout @@ -181,14 +182,13 @@ public class ExamToConfigBindingForm { final EntityKey parentEntityKey = this.pageContext.getParentEntityKey(); final boolean isNew = entityKey == null; - final Exam exam = (isNew) - ? restService - .getBuilder(GetExam.class) - .withURIVariable(API.PARAM_MODEL_ID, parentEntityKey.modelId) - .call() - .onError(error -> this.pageContext.notifyLoadError(EntityType.EXAM, error)) - .getOrThrow() - : null; + final Exam exam = restService + .getBuilder(GetExam.class) + .withURIVariable(API.PARAM_MODEL_ID, parentEntityKey.modelId) + .call() + .onError(error -> this.pageContext.notifyLoadError(EntityType.EXAM, error)) + .getOrThrow(); + // get data or create new. Handle error if happen final ExamConfigurationMap examConfigurationMap = (isNew) @@ -217,8 +217,13 @@ public class ExamToConfigBindingForm { .putStaticValue( Domain.EXAM_CONFIGURATION_MAP.ATTR_EXAM_ID, String.valueOf(examConfigurationMap.examId)) + .putStaticValueIf( + () -> !isNew, + Domain.EXAM_CONFIGURATION_MAP.ATTR_CONFIGURATION_NODE_ID, + String.valueOf(examConfigurationMap.configurationNodeId)) - .addField(FormBuilder.singleSelection( + .addFieldIf( () -> isNew, + () -> FormBuilder.singleSelection( Domain.EXAM_CONFIGURATION_MAP.ATTR_CONFIGURATION_NODE_ID, CONFIG_MAPPING_NAME_TEXT_KEY, String.valueOf(examConfigurationMap.configurationNodeId), @@ -226,6 +231,13 @@ public class ExamToConfigBindingForm { .withSelectionListener(form -> updateFormValuesFromConfigSelection(form, resourceService)) .mandatory()) + .addFieldIf( () -> !isNew, + () -> FormBuilder.text( + Domain.EXAM_CONFIGURATION_MAP.ATTR_CONFIGURATION_NODE_ID, + CONFIG_MAPPING_NAME_TEXT_KEY, + examConfigurationMap.configName) + .readonly(true)) + .addField(FormBuilder.text( Domain.CONFIGURATION_NODE.ATTR_DESCRIPTION, FORM_DESCRIPTION_TEXT_KEY, diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamConfigurationMapDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamConfigurationMapDAOImpl.java index b9eb515c..95da4266 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamConfigurationMapDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ExamConfigurationMapDAOImpl.java @@ -8,6 +8,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.dao.impl; +import static ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.ExamConfigurationMapRecordDynamicSqlSupport.*; import static org.mybatis.dynamic.sql.SqlBuilder.*; import java.util.ArrayList; @@ -23,6 +24,7 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.mybatis.dynamic.sql.SqlBuilder; +import org.mybatis.dynamic.sql.update.UpdateDSL; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -260,15 +262,17 @@ public class ExamConfigurationMapDAOImpl implements ExamConfigurationMapDAO { public Result save(final ExamConfigurationMap data) { return Result.tryCatch(() -> { - final ExamConfigurationMapRecord newRecord = new ExamConfigurationMapRecord( - data.id, - null, - null, - null, - getEncryptionPassword(data), - data.clientGroupId); + final String p = (StringUtils.isNotBlank(data.encryptSecret)) + ? getEncryptionPassword(data) + : null; + + UpdateDSL.updateWithMapper(examConfigurationMapRecordMapper::update, examConfigurationMapRecord) + .set(encryptSecret).equalTo(p ) + .set(clientGroupId).equalToWhenPresent(data.clientGroupId) + .where(id, isEqualTo(data.id)) + .build() + .execute(); - this.examConfigurationMapRecordMapper.updateByPrimaryKeySelective(newRecord); return this.examConfigurationMapRecordMapper.selectByPrimaryKey(data.id); }) .flatMap(this::toDomainModel) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamConfigurationMappingController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamConfigurationMappingController.java index f9df75d5..ee530be4 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamConfigurationMappingController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamConfigurationMappingController.java @@ -133,6 +133,12 @@ public class ExamConfigurationMappingController extends EntityController validForSave(final ExamConfigurationMap entity) { + return super.validForSave(entity) + .map(this::checkPasswordMatch); + } + @Override @RequestMapping( method = RequestMethod.POST, @@ -154,7 +160,6 @@ public class ExamConfigurationMappingController extends EntityController this.examConfigUpdateService.processExamConfigurationMappingChange( entity, this.entityDAO::createNew)) From eac6bccb5f96edbc2452c685996c78fb66c910e2 Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 28 Feb 2024 09:36:25 +0100 Subject: [PATCH 16/31] SEBSERV-408 fixed cache issue --- .../sebserver/gui/content/exam/ExamFormConfigs.java | 10 +++++----- .../sebserver/webservice/servicelayer/dao/ExamDAO.java | 4 +++- .../session/impl/ExamSessionServiceImpl.java | 2 -- .../api/ExamConfigurationMappingController.java | 10 ++++++++++ src/main/resources/messages.properties | 2 +- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamFormConfigs.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamFormConfigs.java index 51a62228..d881a20b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamFormConfigs.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamFormConfigs.java @@ -163,6 +163,11 @@ public class ExamFormConfigs implements TemplateComposer { .noEventPropagation() .publishIf(() -> examConfigEnabled && editable && !configurationTable.hasAnyContent()) + .newAction(ActionDefinition.EXAM_CONFIGURATION_EXAM_CONFIG_VIEW_PROP) + .withParentEntityKey(entityKey) + .withEntityKey(configKey) + .publishIf(() -> examConfigEnabled && readGrant && configurationTable.hasAnyContent(), false) + .newAction(ActionDefinition.EXAM_CONFIGURATION_MODIFY_FROM_LIST) .withParentEntityKey(entityKey) .withSelect( @@ -172,11 +177,6 @@ public class ExamFormConfigs implements TemplateComposer { .noEventPropagation() .publishIf(() -> examConfigEnabled && editable && configurationTable.hasAnyContent(), false) - .newAction(ActionDefinition.EXAM_CONFIGURATION_EXAM_CONFIG_VIEW_PROP) - .withParentEntityKey(entityKey) - .withEntityKey(configKey) - .publishIf(() -> examConfigEnabled && readGrant && configurationTable.hasAnyContent(), false) - .newAction(ActionDefinition.EXAM_CONFIGURATION_DELETE_FROM_LIST) .withEntityKey(entityKey) .withSelect( diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ExamDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ExamDAO.java index a1767302..e90f30ee 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ExamDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ExamDAO.java @@ -216,7 +216,9 @@ public interface ExamDAO extends ActivatableEntityDAO, BulkActionSup * * @param examId the Exam identifier */ @CacheEvict( - cacheNames = ExamSessionCacheService.CACHE_NAME_RUNNING_EXAM, + cacheNames = { + ExamSessionCacheService.CACHE_NAME_RUNNING_EXAM, + ExamSessionCacheService.CACHE_NAME_SEB_CONFIG_EXAM }, key = "#examId") void markUpdate(Long examId); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionServiceImpl.java index bae50e67..5062f00c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/ExamSessionServiceImpl.java @@ -10,11 +10,9 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.session.impl; import java.io.IOException; import java.io.OutputStream; -import java.security.Principal; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.List; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamConfigurationMappingController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamConfigurationMappingController.java index ee530be4..a70af33c 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamConfigurationMappingController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamConfigurationMappingController.java @@ -13,6 +13,8 @@ import java.util.List; import javax.servlet.http.HttpServletRequest; import org.mybatis.dynamic.sql.SqlTable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; import org.springframework.util.MultiValueMap; import org.springframework.validation.FieldError; @@ -57,6 +59,8 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.validation.BeanValidationSe @RequestMapping("${sebserver.webservice.api.admin.endpoint}" + API.EXAM_CONFIGURATION_MAP_ENDPOINT) public class ExamConfigurationMappingController extends EntityController { + private static final Logger log = LoggerFactory.getLogger(ExamConfigurationMappingController.class); + private final ExamDAO examDao; private final ConfigurationNodeDAO configurationNodeDAO; private final ExamConfigUpdateService examConfigUpdateService; @@ -139,6 +143,12 @@ public class ExamConfigurationMappingController extends EntityController notifySaved(final ExamConfigurationMap entity) { + examDao.markUpdate(entity.examId); + return super.notifySaved(entity); + } + @Override @RequestMapping( method = RequestMethod.POST, diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 0e725a13..af355f71 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -679,7 +679,7 @@ sebserver.exam.configuration.list.pleaseSelect=At first please select an exam co sebserver.exam.configuration.action.noconfig.message=There is currently no exam configuration to select.
Please create one in Exam Configurations sebserver.exam.configuration.action.list.new=Add Exam Configuration -sebserver.exam.configuration.action.list.modify=Edit Exam Configuration +sebserver.exam.configuration.action.list.modify=Edit Encryption Password sebserver.exam.configuration.action.list.view=View Exam Configuration sebserver.exam.configuration.action.list.delete=Remove Exam Configuration sebserver.exam.configuration.action.save=Save Exam Configuration From 55501c36d4c823fdc85239468071c1a8ff779fad Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 28 Feb 2024 10:59:42 +0100 Subject: [PATCH 17/31] SEBSERV-502 added deprecation message --- .../gui/content/exam/ProctoringSettingsPopup.java | 13 ++++++++++++- src/main/resources/messages.properties | 2 ++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ProctoringSettingsPopup.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ProctoringSettingsPopup.java index c65449b1..38e9a8f1 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ProctoringSettingsPopup.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ProctoringSettingsPopup.java @@ -111,6 +111,13 @@ public class ProctoringSettingsPopup { private final static LocTextKey RESET_SUCCESS_KEY = new LocTextKey("sebserver.exam.proctoring.form.resetOk"); + private final static LocTextKey DEPRECATION_MESSAGE = + new LocTextKey("sebserver.exam.proctoring.deprecation.message"); + private final static LocTextKey DEPRECATION_NOTE = + new LocTextKey("sebserver.exam.proctoring.deprecation.title"); + + + Function settingsFunction(final PageService pageService, final boolean modifyGrant) { return action -> { @@ -125,7 +132,7 @@ public class ProctoringSettingsPopup { action.pageContext().getParent().getShell(), pageService.getWidgetFactory()) .setDialogWidth(860) - .setDialogHeight(600); + .setDialogHeight(650); final ResetButtonHandler resetButtonHandler = new ResetButtonHandler(); if (modifyGrant) { @@ -326,6 +333,10 @@ public class ProctoringSettingsPopup { final RestService restService = this.pageService.getRestService(); final EntityKey entityKey = this.pageContext.getEntityKey(); + final Composite warningPanel = this.pageService.getWidgetFactory().createWarningPanel(parent); + this.pageService.getWidgetFactory().labelLocalized(warningPanel, WidgetFactory.CustomVariant.TITLE_LABEL, DEPRECATION_NOTE); + this.pageService.getWidgetFactory().labelLocalized(warningPanel, WidgetFactory.CustomVariant.SUBTITLE, DEPRECATION_MESSAGE, null); + final Composite content = this.pageService .getWidgetFactory() .createPopupScrollComposite(parent); diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index af355f71..434fdaee 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -830,6 +830,8 @@ sebserver.exam.proctoring.form.collect.strategy=Collecting Room Strategy sebserver.exam.proctoring.form.collect.strategy.tooltip=This specifies the strategy how connecting SEB clients are collected into proctoring rooms sebserver.exam.proctoring.form.collectingRoomSize=Collecting Room Size sebserver.exam.proctoring.form.collectingRoomSize.tooltip=The size of proctor rooms to collect connecting SEB clients into. +sebserver.exam.proctoring.deprecation.title=Deprecation Note: +sebserver.exam.proctoring.deprecation.message=The SEB Server live proctoring integration with Zoom and Jitsi Meet has been deprecated since this version of SEB Server.
This means live proctoring is still available for dedicated SEB versions, but not actively maintained and supported any more. sebserver.exam.proctoring.form.appkey.jitsi=App Key sebserver.exam.proctoring.form.appkey.jitsi.tooltip=The application key of the proctoring service server From fa5d3fed2405121af874b564f81c16a6f12138dd Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 28 Feb 2024 11:07:01 +0100 Subject: [PATCH 18/31] minor fix with quit password change in Exam --- .../webservice/weblayer/api/ExamAdministrationController.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java index 75df0c6f..9cbb5076 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/ExamAdministrationController.java @@ -707,6 +707,9 @@ public class ExamAdministrationController extends EntityController { examSessionService.hasActiveSEBClientConnections(exam.id)) { final Exam oldExam = this.examDAO.byPK(exam.id).getOrThrow(); final CharSequence pwd = cryptor.decrypt(oldExam.quitPassword).getOr(oldExam.quitPassword); + if (StringUtils.isBlank(pwd) && StringUtils.isBlank(exam.quitPassword)) { + return exam; + } if (!Objects.equals(pwd, exam.quitPassword)) { throw new APIMessageException(APIMessage.fieldValidationError( new FieldError( From 51a0586c58fd8260a83c4ab7a6a1af1811c412e9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Feb 2024 10:53:59 +0000 Subject: [PATCH 19/31] Bump readthedocs-sphinx-search from 0.1.1 to 0.3.2 in /docs Bumps [readthedocs-sphinx-search](https://github.com/readthedocs/readthedocs-sphinx-search) from 0.1.1 to 0.3.2. - [Changelog](https://github.com/readthedocs/readthedocs-sphinx-search/blob/main/CHANGELOG.rst) - [Commits](https://github.com/readthedocs/readthedocs-sphinx-search/compare/0.1.1...0.3.2) --- updated-dependencies: - dependency-name: readthedocs-sphinx-search dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- docs/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index 53d44466..3d5bdc5b 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,5 @@ docutils<0.18 sphinx==5.3.0 sphinx_rtd_theme==2.0.0 -readthedocs-sphinx-search==0.1.1 +readthedocs-sphinx-search==0.3.2 urllib3==1.26.13 \ No newline at end of file From 4d55104a0b3c3ca17228db929230ed6446101eac Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 28 Feb 2024 13:39:31 +0100 Subject: [PATCH 20/31] debug minimal docker setup --- .../sebserver/webservice/WebserviceInit.java | 28 +++++++++++-------- .../dao/impl/WebserviceInfoDAOImpl.java | 1 + 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInit.java b/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInit.java index 60be47b5..08956935 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInit.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/WebserviceInit.java @@ -76,22 +76,26 @@ public class WebserviceInit implements ApplicationListener "); SEBServerInit.INIT_LOGGER.info("----> Register Webservice: {}", this.webserviceInfo.getWebserviceUUID()); - if (this.webserviceInfoDAO.isInitialized()) { - this.registerWebservice(); + try { + if (this.webserviceInfoDAO.isInitialized()) { + this.registerWebservice(); - // Apply migration if needed and possible - SEBServerInit.INIT_LOGGER.info("----> "); - this.sebServerMigrationStrategy.applyMigration(); - SEBServerInit.INIT_LOGGER.info("----> "); + // Apply migration if needed and possible + SEBServerInit.INIT_LOGGER.info("----> "); + this.sebServerMigrationStrategy.applyMigration(); + SEBServerInit.INIT_LOGGER.info("----> "); - } else { + } else { - // Apply migration if needed and possible - SEBServerInit.INIT_LOGGER.info("----> "); - this.sebServerMigrationStrategy.applyMigration(); - SEBServerInit.INIT_LOGGER.info("----> "); + // Apply migration if needed and possible + SEBServerInit.INIT_LOGGER.info("----> "); + this.sebServerMigrationStrategy.applyMigration(); + SEBServerInit.INIT_LOGGER.info("----> "); - this.registerWebservice(); + this.registerWebservice(); + } + } catch (final Exception e) { + SEBServerInit.INIT_LOGGER.error("Failed to apply data import and migration --> ", e); } SEBServerInit.INIT_LOGGER.info("----> "); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/WebserviceInfoDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/WebserviceInfoDAOImpl.java index b2d09865..dee1fe6f 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/WebserviceInfoDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/WebserviceInfoDAOImpl.java @@ -57,6 +57,7 @@ public class WebserviceInfoDAOImpl implements WebserviceInfoDAO { .execute(); return true; } catch (final Exception e) { + log.warn("DB Context not initialized: ", e); return false; } } From a75397180807676f731f3bf03b6be59f46a47b6f Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 28 Feb 2024 14:58:59 +0100 Subject: [PATCH 21/31] debug minimal docker setup --- .../sebserver/webservice/AdminUserInitializer.java | 11 ++++++++++- .../servicelayer/dao/impl/WebserviceInfoDAOImpl.java | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/AdminUserInitializer.java b/src/main/java/ch/ethz/seb/sebserver/webservice/AdminUserInitializer.java index cbd73b8a..86caaaa3 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/AdminUserInitializer.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/AdminUserInitializer.java @@ -12,10 +12,12 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashSet; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Component; @@ -44,15 +46,18 @@ class AdminUserInitializer { private final boolean initializeAdmin; private final String adminName; private final String orgName; + private final Environment environment; public AdminUserInitializer( final UserDAO userDAO, final InstitutionDAO institutionDAO, + final Environment environment, @Qualifier(WebSecurityConfig.USER_PASSWORD_ENCODER_BEAN_NAME) final PasswordEncoder passwordEncoder, @Value("${sebserver.init.adminaccount.gen-on-init:false}") final boolean initializeAdmin, @Value("${sebserver.init.adminaccount.username:seb-server-admin}") final String adminName, @Value("${sebserver.init.organisation.name:[SET_ORGANIZATION_NAME]}") final String orgName) { + this.environment = environment; this.userDAO = userDAO; this.institutionDAO = institutionDAO; this.passwordEncoder = passwordEncoder; @@ -89,7 +94,11 @@ class AdminUserInitializer { } } } else { - final CharSequence generateAdminPassword = this.generateAdminPassword(); + final String initPWD = environment.getProperty("sebserver.init.adminaccount.init.pwd", ""); + final CharSequence generateAdminPassword = StringUtils.isNotBlank(initPWD) + ? initPWD : + this.generateAdminPassword(); + Long institutionId = this.institutionDAO.allMatching(new FilterMap()) .getOrElse(Collections::emptyList) .stream() diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/WebserviceInfoDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/WebserviceInfoDAOImpl.java index dee1fe6f..cec3a9d3 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/WebserviceInfoDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/WebserviceInfoDAOImpl.java @@ -57,7 +57,7 @@ public class WebserviceInfoDAOImpl implements WebserviceInfoDAO { .execute(); return true; } catch (final Exception e) { - log.warn("DB Context not initialized: ", e); + log.warn("DB Context not initialized yet: {}", e.getMessage()); return false; } } From 93b450fa6715940e39ea2d4cc47ed81a56e80e3b Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 28 Feb 2024 16:23:56 +0100 Subject: [PATCH 22/31] github actions update --- .github/workflows/buildReporting.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/buildReporting.yml b/.github/workflows/buildReporting.yml index a0dd5354..52608a2d 100644 --- a/.github/workflows/buildReporting.yml +++ b/.github/workflows/buildReporting.yml @@ -18,16 +18,16 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up JDK 8 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '8' distribution: 'adopt' - name: Cache Maven packages - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -37,7 +37,7 @@ jobs: run: mvn clean install -e -P let_reporting - name: Reporting - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: flags: unittests name: SEB Server Build @@ -69,16 +69,16 @@ jobs: echo ${{ env.TAG_NAME }} - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '17' distribution: 'adopt' - name: Cache Maven packages - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ~/.m2 key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} @@ -92,7 +92,7 @@ jobs: name: Simplify package name run: mv target/seb-server-${{ env.TAG_NAME }}-${{ env.SHA }}.jar target/seb-server.jar - - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: Package path: target/seb-server.jar @@ -132,7 +132,7 @@ jobs: password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 # Install the cosign tool except on PR # https://github.com/sigstore/cosign-installer @@ -142,7 +142,7 @@ jobs: uses: sigstore/cosign-installer@main - name: Download a single artifact - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: Package - From 16d06bd13f1ad729dc66b99b03ae5292a85dd967 Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 29 Feb 2024 10:09:52 +0100 Subject: [PATCH 23/31] SEBSERV-507 added CONTRIBUTION.md --- CONTRIBUTION.md | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ README.rst | 1 + 2 files changed, 54 insertions(+) create mode 100644 CONTRIBUTION.md diff --git a/CONTRIBUTION.md b/CONTRIBUTION.md new file mode 100644 index 00000000..fb0dbcc1 --- /dev/null +++ b/CONTRIBUTION.md @@ -0,0 +1,53 @@ +# Contributing to SEB Server +We want to make contributing to this project as easy and transparent as possible, whether it's: + +- Give us a star +- Reporting a bug +- Submitting a fix +- Proposing new features +- Becoming a SEB Alliance member + +## We Develop with Github +We use github to host code, to track issues and feature requests, as well as accept pull requests. + +## We Use Git-Flow for Code Contributions +Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow)). We actively welcome your pull requests: + +1. Fork the repo and create your branch from `development`. The development branch always has the newest changes. +2. If you've added code that should be tested, add tests. +3. If you introduce new API also add clear documentation. +4. Ensure the test suite passes. +5. Make sure your code lints. +6. Issue that pull request! + +## Any contributions you make will be under the Mozilla Public License Version 2.0 +In short, when you submit code changes, your submissions are understood to be under the same [Mozilla Public License](https://github.com/SafeExamBrowser/seb-server?tab=MPL-2.0-1-ov-file) that covers the project. Feel free to contact the maintainers if that's a concern. + +## Report bugs using Github's Issue +We use [Github issues](https://github.com/SafeExamBrowser/seb-server/issues) to track public bugs. Report a bug by [opening a new issue](); + +## Write bug reports with detail, background, and sample code +**Before enter a new bug-report, ensure the bug was not already reported** + +Please fill and provide all the information suggested by the bug-report template +Great Bug Reports tend to have: + +- A quick summary and/or background +- Steps to reproduce + - Be specific! + - Give sample code if you can. Can also be Pseudocode. +- What you expected would happen +- What actually happens +- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) + +## Use a Consistent Coding Style +Have a close look to the existing code stile that is used within SEB Server and adapt to it as close as possible. +We reserve the right to adapt contributed code to the code style matching SEB Server code style before or after a pull request. + +## Becoming a SEB Alliance member +The [SEB Alliance](https://www.safeexambrowser.org/alliance/members.html) is the body which sustains ongoing funding of the Safe Exam Browser open source project to continue its maintenance, development and support activities. ETH Zurich provides the infrastructure for the management and the software engineering of the SEB project and appoints an alliance manager who will provide administrative support to the SEB Alliance, and ensure the day-to-day running of the SEB Alliance. ETH Zurich leads the Alliance and offers different contribution levels to parties interested in the evolution of the SEB open source project. + +More information about [joining](https://www.safeexambrowser.org/alliance/join.html) the Alliance is available in our [benefits](https://www.safeexambrowser.org/alliance/benefits.html) and [documents](https://www.safeexambrowser.org/alliance/documents.html) section. + +## License +By contributing, you agree that your contributions will be licensed under its [Mozilla Public License](https://github.com/SafeExamBrowser/seb-server?tab=MPL-2.0-1-ov-file). diff --git a/README.rst b/README.rst index 1213649d..c556a2d0 100644 --- a/README.rst +++ b/README.rst @@ -142,6 +142,7 @@ Getting started with SEB Server For a complete SEB Server user guide please go to `SEB Server User Guide `_ + Project Background ------------------ From c96c950f6e892ee4a292703386df1dd1b302d5a5 Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 29 Feb 2024 10:11:33 +0100 Subject: [PATCH 24/31] SEBSERV-507 added CONTRIBUTION.md --- CONTRIBUTION.md => CONTRIBUTING.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename CONTRIBUTION.md => CONTRIBUTING.md (100%) diff --git a/CONTRIBUTION.md b/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTION.md rename to CONTRIBUTING.md From a9d4424368293e8f01613d1eb87b12178f0d1cad Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 29 Feb 2024 10:15:03 +0100 Subject: [PATCH 25/31] SEBSERV-507 added CONTRIBUTION.md --- CONTRIBUTING.md => CONTRIBUTING | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename CONTRIBUTING.md => CONTRIBUTING (100%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING similarity index 100% rename from CONTRIBUTING.md rename to CONTRIBUTING From 169a709fedd2f75effc0c4481f9615ec72dc27ae Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 29 Feb 2024 10:18:22 +0100 Subject: [PATCH 26/31] SEBSERV-507 added CONTRIBUTION.md --- CONTRIBUTING => CONTRIBUTING.md | 0 README.rst | 4 ++++ 2 files changed, 4 insertions(+) rename CONTRIBUTING => CONTRIBUTING.md (100%) diff --git a/CONTRIBUTING b/CONTRIBUTING.md similarity index 100% rename from CONTRIBUTING rename to CONTRIBUTING.md diff --git a/README.rst b/README.rst index c556a2d0..f124f559 100644 --- a/README.rst +++ b/README.rst @@ -147,3 +147,7 @@ Project Background ------------------ The SEB Server is currently build and maintained by `ETH Zürich `_ and by the `Swiss MOOC Service `_ that is founded by leading Swiss universities EPFL, ETH, SUPSI, USI and HES-SO. The Swiss MOOC Service was financially supported from 2018-2020 by the `Swissuniversities´ P5 program `_. + +Contribution +------------ +.. include:: CONTRIBUTING.md From 75a56cd82964deca12cc9284c47c48473b907c53 Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 29 Feb 2024 10:19:18 +0100 Subject: [PATCH 27/31] SEBSERV-507 added CONTRIBUTION.md --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index f124f559..a0a3cba6 100644 --- a/README.rst +++ b/README.rst @@ -150,4 +150,4 @@ The SEB Server is currently build and maintained by `ETH Zürich Date: Thu, 29 Feb 2024 10:29:16 +0100 Subject: [PATCH 28/31] SEBSERV-507 added CONTRIBUTION.md --- CONTRIBUTING.md | 3 --- README.rst | 58 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fb0dbcc1..32cf344b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -48,6 +48,3 @@ We reserve the right to adapt contributed code to the code style matching SEB Se The [SEB Alliance](https://www.safeexambrowser.org/alliance/members.html) is the body which sustains ongoing funding of the Safe Exam Browser open source project to continue its maintenance, development and support activities. ETH Zurich provides the infrastructure for the management and the software engineering of the SEB project and appoints an alliance manager who will provide administrative support to the SEB Alliance, and ensure the day-to-day running of the SEB Alliance. ETH Zurich leads the Alliance and offers different contribution levels to parties interested in the evolution of the SEB open source project. More information about [joining](https://www.safeexambrowser.org/alliance/join.html) the Alliance is available in our [benefits](https://www.safeexambrowser.org/alliance/benefits.html) and [documents](https://www.safeexambrowser.org/alliance/documents.html) section. - -## License -By contributing, you agree that your contributions will be licensed under its [Mozilla Public License](https://github.com/SafeExamBrowser/seb-server?tab=MPL-2.0-1-ov-file). diff --git a/README.rst b/README.rst index a0a3cba6..6dfd816a 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,7 @@ -Master: +Safe Exam Browser (SEB) Server +-------------------------------- + +Master: .. image:: https://github.com/SafeExamBrowser/seb-server/actions/workflows/buildReporting.yml/badge.svg?branch=master :target: https://github.com/SafeExamBrowser/seb-server/actions @@ -148,6 +151,53 @@ Project Background The SEB Server is currently build and maintained by `ETH Zürich `_ and by the `Swiss MOOC Service `_ that is founded by leading Swiss universities EPFL, ETH, SUPSI, USI and HES-SO. The Swiss MOOC Service was financially supported from 2018-2020 by the `Swissuniversities´ P5 program `_. -Contribution ------------- -.. include:: ./CONTRIBUTING.md +Contributing to SEB Server +------------------ +We want to make contributing to this project as easy and transparent as possible, whether it's: + +- Give us a star +- Reporting a bug +- Submitting a fix +- Proposing new features +- Becoming a SEB Alliance member + +We use github to host code, to track issues and feature requests, as well as accept pull requests. +And we use [Github issues](https://github.com/SafeExamBrowser/seb-server/issues) to track public bugs. +Report a bug by [opening a new issue](); + +**Before enter a new bug-report, ensure the bug was not already reported** +Please fill and provide all the information suggested by the bug-report template +Great Bug Reports tend to have: + +- A quick summary and/or background +- Steps to reproduce + - Be specific! + - Give sample code if you can. Can also be Pseudocode. +- What you expected would happen +- What actually happens +- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) + +** We Use Git-Flow for Code Contributions** +Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow)). We actively welcome your pull requests: + +1. Fork the repo and create your branch from `development`. The development branch always has the newest changes. +2. If you've added code that should be tested, add tests. +3. If you introduce new API also add clear documentation. +4. Ensure the test suite passes. +5. Make sure your code lints. +6. Issue that pull request! + +**Use a Consistent Coding Style** + +Have a close look to the existing code stile that is used within SEB Server and adapt to it as close as possible. +We reserve the right to adapt contributed code to the code style matching SEB Server code style before or after a pull request. + +**Any contributions you make will be under the Mozilla Public License Version 2.0** + +In short, when you submit code changes, your submissions are understood to be under the same [Mozilla Public License](https://github.com/SafeExamBrowser/seb-server?tab=MPL-2.0-1-ov-file) that covers the project. Feel free to contact the maintainers if that's a concern. + +**Becoming a SEB Alliance member** +The [SEB Alliance](https://www.safeexambrowser.org/alliance/members.html) is the body which sustains ongoing funding of the Safe Exam Browser open source project to continue its maintenance, development and support activities. ETH Zurich provides the infrastructure for the management and the software engineering of the SEB project and appoints an alliance manager who will provide administrative support to the SEB Alliance, and ensure the day-to-day running of the SEB Alliance. ETH Zurich leads the Alliance and offers different contribution levels to parties interested in the evolution of the SEB open source project. + +More information about [joining](https://www.safeexambrowser.org/alliance/join.html) the Alliance is available in our [benefits](https://www.safeexambrowser.org/alliance/benefits.html) and [documents](https://www.safeexambrowser.org/alliance/documents.html) section. + From 613860aaa7c78bb1eaf8b6baa428b9887b4cb67b Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 29 Feb 2024 10:35:41 +0100 Subject: [PATCH 29/31] SEBSERV-507 added CONTRIBUTION.md --- README.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.rst b/README.rst index 6dfd816a..be1d7ee6 100644 --- a/README.rst +++ b/README.rst @@ -162,23 +162,24 @@ We want to make contributing to this project as easy and transparent as possible - Becoming a SEB Alliance member We use github to host code, to track issues and feature requests, as well as accept pull requests. -And we use [Github issues](https://github.com/SafeExamBrowser/seb-server/issues) to track public bugs. +And we use `Github issues `_ to track public bugs. Report a bug by [opening a new issue](); **Before enter a new bug-report, ensure the bug was not already reported** + Please fill and provide all the information suggested by the bug-report template Great Bug Reports tend to have: - A quick summary and/or background - Steps to reproduce - - Be specific! - - Give sample code if you can. Can also be Pseudocode. +- Be specific and give sample code if you can. Can also be Pseudocode. - What you expected would happen - What actually happens - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) ** We Use Git-Flow for Code Contributions** -Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow)). We actively welcome your pull requests: + +Pull requests are the best way to propose changes to the codebase. We use `Github Flow `_. We actively welcome your pull requests: 1. Fork the repo and create your branch from `development`. The development branch always has the newest changes. 2. If you've added code that should be tested, add tests. @@ -194,10 +195,10 @@ We reserve the right to adapt contributed code to the code style matching SEB Se **Any contributions you make will be under the Mozilla Public License Version 2.0** -In short, when you submit code changes, your submissions are understood to be under the same [Mozilla Public License](https://github.com/SafeExamBrowser/seb-server?tab=MPL-2.0-1-ov-file) that covers the project. Feel free to contact the maintainers if that's a concern. +In short, when you submit code changes, your submissions are understood to be under the same `Mozilla Public License `_ that covers the project. Feel free to contact the maintainers if that's a concern. **Becoming a SEB Alliance member** -The [SEB Alliance](https://www.safeexambrowser.org/alliance/members.html) is the body which sustains ongoing funding of the Safe Exam Browser open source project to continue its maintenance, development and support activities. ETH Zurich provides the infrastructure for the management and the software engineering of the SEB project and appoints an alliance manager who will provide administrative support to the SEB Alliance, and ensure the day-to-day running of the SEB Alliance. ETH Zurich leads the Alliance and offers different contribution levels to parties interested in the evolution of the SEB open source project. +The `SEB Alliance `_ is the body which sustains ongoing funding of the Safe Exam Browser open source project to continue its maintenance, development and support activities. ETH Zurich provides the infrastructure for the management and the software engineering of the SEB project and appoints an alliance manager who will provide administrative support to the SEB Alliance, and ensure the day-to-day running of the SEB Alliance. ETH Zurich leads the Alliance and offers different contribution levels to parties interested in the evolution of the SEB open source project. -More information about [joining](https://www.safeexambrowser.org/alliance/join.html) the Alliance is available in our [benefits](https://www.safeexambrowser.org/alliance/benefits.html) and [documents](https://www.safeexambrowser.org/alliance/documents.html) section. +More information about `joining `_ the Alliance is available in our `benefits `_ and `documents `_ section. From 071effbaaf073788a81f13425eab37523ce8503b Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 29 Feb 2024 10:37:17 +0100 Subject: [PATCH 30/31] SEBSERV-507 added CONTRIBUTION.md --- README.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index be1d7ee6..ffd1c873 100644 --- a/README.rst +++ b/README.rst @@ -177,7 +177,7 @@ Great Bug Reports tend to have: - What actually happens - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) -** We Use Git-Flow for Code Contributions** +**We Use Git-Flow for Code Contributions** Pull requests are the best way to propose changes to the codebase. We use `Github Flow `_. We actively welcome your pull requests: @@ -198,6 +198,7 @@ We reserve the right to adapt contributed code to the code style matching SEB Se In short, when you submit code changes, your submissions are understood to be under the same `Mozilla Public License `_ that covers the project. Feel free to contact the maintainers if that's a concern. **Becoming a SEB Alliance member** + The `SEB Alliance `_ is the body which sustains ongoing funding of the Safe Exam Browser open source project to continue its maintenance, development and support activities. ETH Zurich provides the infrastructure for the management and the software engineering of the SEB project and appoints an alliance manager who will provide administrative support to the SEB Alliance, and ensure the day-to-day running of the SEB Alliance. ETH Zurich leads the Alliance and offers different contribution levels to parties interested in the evolution of the SEB open source project. More information about `joining `_ the Alliance is available in our `benefits `_ and `documents `_ section. From 73aeda28a3bf67cd81f1f2bf9610ec1c5c77c4ac Mon Sep 17 00:00:00 2001 From: anhefti Date: Thu, 29 Feb 2024 10:38:42 +0100 Subject: [PATCH 31/31] SEBSERV-507 added CONTRIBUTION.md --- CONTRIBUTING.md | 50 ------------------------------------------------- 1 file changed, 50 deletions(-) delete mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index 32cf344b..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Contributing to SEB Server -We want to make contributing to this project as easy and transparent as possible, whether it's: - -- Give us a star -- Reporting a bug -- Submitting a fix -- Proposing new features -- Becoming a SEB Alliance member - -## We Develop with Github -We use github to host code, to track issues and feature requests, as well as accept pull requests. - -## We Use Git-Flow for Code Contributions -Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow)). We actively welcome your pull requests: - -1. Fork the repo and create your branch from `development`. The development branch always has the newest changes. -2. If you've added code that should be tested, add tests. -3. If you introduce new API also add clear documentation. -4. Ensure the test suite passes. -5. Make sure your code lints. -6. Issue that pull request! - -## Any contributions you make will be under the Mozilla Public License Version 2.0 -In short, when you submit code changes, your submissions are understood to be under the same [Mozilla Public License](https://github.com/SafeExamBrowser/seb-server?tab=MPL-2.0-1-ov-file) that covers the project. Feel free to contact the maintainers if that's a concern. - -## Report bugs using Github's Issue -We use [Github issues](https://github.com/SafeExamBrowser/seb-server/issues) to track public bugs. Report a bug by [opening a new issue](); - -## Write bug reports with detail, background, and sample code -**Before enter a new bug-report, ensure the bug was not already reported** - -Please fill and provide all the information suggested by the bug-report template -Great Bug Reports tend to have: - -- A quick summary and/or background -- Steps to reproduce - - Be specific! - - Give sample code if you can. Can also be Pseudocode. -- What you expected would happen -- What actually happens -- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) - -## Use a Consistent Coding Style -Have a close look to the existing code stile that is used within SEB Server and adapt to it as close as possible. -We reserve the right to adapt contributed code to the code style matching SEB Server code style before or after a pull request. - -## Becoming a SEB Alliance member -The [SEB Alliance](https://www.safeexambrowser.org/alliance/members.html) is the body which sustains ongoing funding of the Safe Exam Browser open source project to continue its maintenance, development and support activities. ETH Zurich provides the infrastructure for the management and the software engineering of the SEB project and appoints an alliance manager who will provide administrative support to the SEB Alliance, and ensure the day-to-day running of the SEB Alliance. ETH Zurich leads the Alliance and offers different contribution levels to parties interested in the evolution of the SEB open source project. - -More information about [joining](https://www.safeexambrowser.org/alliance/join.html) the Alliance is available in our [benefits](https://www.safeexambrowser.org/alliance/benefits.html) and [documents](https://www.safeexambrowser.org/alliance/documents.html) section.