From 9e82fac386429c5e586e7042f115ed4f2112eb2b Mon Sep 17 00:00:00 2001 From: anhefti Date: Mon, 18 Mar 2024 13:16:09 +0100 Subject: [PATCH 1/9] code cleanup --- src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java index 9cec7f43..abb8bfe2 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/exam/Exam.java @@ -281,7 +281,7 @@ public final class Exam implements GrantEntity { } return result; } else { - return null; + return Collections.emptyList(); } } From d20883c2fd74b9547dcecfd3e980687e4370c8a2 Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 20 Mar 2024 08:44:26 +0100 Subject: [PATCH 2/9] Fixed some Spring security related warnings and converted http.ignore paths to http...permitAll configs where possible --- .../ethz/seb/sebserver/WebSecurityConfig.java | 19 ++----------- .../sebserver/gui/GuiWebsecurityConfig.java | 28 +++++++++++++++---- .../weblayer/WebServiceSecurityConfig.java | 9 +++--- .../WebserviceResourceConfiguration.java | 12 ++++++++ 4 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/WebSecurityConfig.java b/src/main/java/ch/ethz/seb/sebserver/WebSecurityConfig.java index c23f236e..177bb475 100644 --- a/src/main/java/ch/ethz/seb/sebserver/WebSecurityConfig.java +++ b/src/main/java/ch/ethz/seb/sebserver/WebSecurityConfig.java @@ -40,9 +40,6 @@ import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; @Order(7) public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements ErrorController { - private static final String ERROR_PATH = "/sebserver/error"; - private static final String CHECK_PATH = "/sebserver/check"; - @Value("${sebserver.webservice.http.redirect.gui}") private String guiRedirect; @Value("${sebserver.webservice.api.exam.endpoint.discovery}") @@ -77,23 +74,11 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements E return new BCryptPasswordEncoder(4); } - @Override - public void configure(final WebSecurity web) { - web - .ignoring() - .antMatchers(ERROR_PATH) - .antMatchers(CHECK_PATH) - .antMatchers(this.examAPIDiscoveryEndpoint) - .antMatchers(this.adminAPIEndpoint + API.INFO_ENDPOINT + API.LOGO_PATH_SEGMENT + "/**") - .antMatchers(this.adminAPIEndpoint + API.INFO_ENDPOINT + API.INFO_INST_PATH_SEGMENT + "/**") - .antMatchers(this.adminAPIEndpoint + API.REGISTER_ENDPOINT); - } - - @RequestMapping(CHECK_PATH) + @RequestMapping(API.CHECK_PATH) public void check() throws IOException { } - @RequestMapping(ERROR_PATH) + @RequestMapping(API.ERROR_PATH) public void handleError(final HttpServletResponse response) throws IOException { response.getOutputStream().print(response.getStatus()); response.setHeader(HttpHeaders.LOCATION, this.guiRedirect); diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/GuiWebsecurityConfig.java b/src/main/java/ch/ethz/seb/sebserver/gui/GuiWebsecurityConfig.java index caacff0c..8ff2351e 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/GuiWebsecurityConfig.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/GuiWebsecurityConfig.java @@ -42,6 +42,10 @@ public class GuiWebsecurityConfig extends WebSecurityConfigurerAdapter { private String remoteProctoringViewServletEndpoint; @Value("${springdoc.api-docs.enabled:false}") private boolean springDocsAPIEnabled; + @Value("${sebserver.webservice.api.exam.endpoint.discovery}") + private String examAPIDiscoveryEndpoint; + @Value("${sebserver.webservice.api.admin.endpoint}") + private String adminAPIEndpoint; /** Gui-service related public URLS from spring web security perspective */ public static final RequestMatcher PUBLIC_URLS = new OrRequestMatcher( @@ -52,28 +56,40 @@ public class GuiWebsecurityConfig extends WebSecurityConfigurerAdapter { // project specific static resources new AntPathRequestMatcher("/images/**"), - new AntPathRequestMatcher("/favicon.ico")); + new AntPathRequestMatcher("/favicon.ico") + ); @Override public void configure(final WebSecurity web) { web - .ignoring() - .requestMatchers(PUBLIC_URLS) - .antMatchers(this.guiEntryPoint) - .antMatchers(this.remoteProctoringEndpoint) - .antMatchers(this.remoteProctoringEndpoint + this.remoteProctoringViewServletEndpoint + "/*"); + .ignoring() + .antMatchers(this.guiEntryPoint) + ; if (this.springDocsAPIEnabled) { web.ignoring().antMatchers("/swagger-ui.html", "/swagger-ui/**", "/v3/api-docs/**"); } } + + @Override public void configure(final HttpSecurity http) throws Exception { http .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() + .authorizeRequests() + .antMatchers(this.remoteProctoringEndpoint).permitAll() + .antMatchers(this.remoteProctoringEndpoint + this.remoteProctoringViewServletEndpoint + "/*").permitAll() + .requestMatchers(PUBLIC_URLS).permitAll() + .antMatchers(API.ERROR_PATH).permitAll() + .antMatchers(API.CHECK_PATH).permitAll() + .antMatchers(this.examAPIDiscoveryEndpoint).permitAll() + .antMatchers(adminAPIEndpoint + API.INFO_ENDPOINT + API.LOGO_PATH_SEGMENT + "/**").permitAll() + .antMatchers(adminAPIEndpoint + API.INFO_ENDPOINT + API.INFO_INST_PATH_SEGMENT + "/**").permitAll() + .antMatchers(adminAPIEndpoint + API.REGISTER_ENDPOINT).permitAll() + .and() .antMatcher("/**") .authorizeRequests() .anyRequest() diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/WebServiceSecurityConfig.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/WebServiceSecurityConfig.java index 76993e77..0624fdb9 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/WebServiceSecurityConfig.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/WebServiceSecurityConfig.java @@ -13,6 +13,7 @@ import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import ch.ethz.seb.sebserver.gbl.api.API; import org.apache.catalina.filters.RemoteIpFilter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,18 +51,18 @@ import ch.ethz.seb.sebserver.webservice.weblayer.oauth.WebClientDetailsService; import ch.ethz.seb.sebserver.webservice.weblayer.oauth.WebserviceResourceConfiguration; /** This is the main web-security Spring configuration for SEB-Server webservice API - * + *

* Currently two separated Rest API's are implemented, one for administration and maintenance * of the SEB-Server (AdminAPI) and one for SEB-Client connection on running exams and eventually * also for LMS communication), if needed (ExamAPI). The AdministrationAPI uses OAuth 2 password * grant with refresh-token, same as in the prototype and the ExamAPI uses the client_credential grant. - * + *

* There is a Spring Authorization-Server defining this two clients (AdminAPIClient and ExamAPIClient) as well as * two Spring Resource-Server for the separation of the different API's - * + *

* The endpoint of the AdministrationAPI can be configured within the key; sebserver.webservice.api.admin.endpoint * and is by default set to "/admin-api/**" - * + *

* The endpoint of the ExamAPI can be configured within the key; sebserver.webservice.api.exam.endpoint * and is by default set to "/exam-api/**" */ @WebServiceProfile diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/oauth/WebserviceResourceConfiguration.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/oauth/WebserviceResourceConfiguration.java index f7e70ad2..5957467b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/oauth/WebserviceResourceConfiguration.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/oauth/WebserviceResourceConfiguration.java @@ -11,6 +11,8 @@ package ch.ethz.seb.sebserver.webservice.weblayer.oauth; import java.util.Arrays; import java.util.List; +import ch.ethz.seb.sebserver.gbl.api.API; +import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.http.SessionCreationPolicy; @@ -30,6 +32,8 @@ public abstract class WebserviceResourceConfiguration extends ResourceServerConf public static final String ADMIN_API_RESOURCE_ID = "seb-server-administration-api"; /** The resource identifier of the Exam API resources */ public static final String EXAM_API_RESOURCE_ID = "seb-server-exam-api"; + @Value("${sebserver.webservice.api.exam.endpoint.discovery}") + private String examAPIDiscoveryEndpoint; public WebserviceResourceConfiguration( final TokenStore tokenStore, @@ -74,6 +78,14 @@ public abstract class WebserviceResourceConfiguration extends ResourceServerConf .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() + .authorizeRequests() + .antMatchers(API.ERROR_PATH).permitAll() + .antMatchers(API.CHECK_PATH).permitAll() + .antMatchers(this.examAPIDiscoveryEndpoint).permitAll() + .antMatchers(configurerAdapter.apiEndpoint + API.INFO_ENDPOINT + API.LOGO_PATH_SEGMENT + "/**").permitAll() + .antMatchers(configurerAdapter.apiEndpoint + API.INFO_ENDPOINT + API.INFO_INST_PATH_SEGMENT + "/**").permitAll() + .antMatchers(configurerAdapter.apiEndpoint + API.REGISTER_ENDPOINT).permitAll() + .and() .antMatcher(configurerAdapter.apiEndpoint + "/**") .authorizeRequests() .anyRequest() From a40b65ea0082602b0ef461b9ab310255261d59d4 Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 20 Mar 2024 08:45:03 +0100 Subject: [PATCH 3/9] Fixed CI pipelenie + codecov token --- .github/workflows/buildReporting.yml | 4 +++- src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/buildReporting.yml b/.github/workflows/buildReporting.yml index b5923992..28f4759f 100644 --- a/.github/workflows/buildReporting.yml +++ b/.github/workflows/buildReporting.yml @@ -53,6 +53,8 @@ jobs: - name: Reporting uses: codecov/codecov-action@v4 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: flags: unittests name: SEB Server Build @@ -92,7 +94,7 @@ jobs: uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 + uses: docker/setup-buildx-action@v4 - name: Login to DockerHub uses: docker/login-action@v2 diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java b/src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java index 4a5b7964..a18ecdb9 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java +++ b/src/main/java/ch/ethz/seb/sebserver/gbl/api/API.java @@ -12,6 +12,9 @@ import ch.ethz.seb.sebserver.gbl.model.sebconfig.ConfigurationNode; public final class API { + public static final String ERROR_PATH = "/sebserver/error"; + public static final String CHECK_PATH = "/sebserver/check"; + public enum BulkActionType { HARD_DELETE, DEACTIVATE, From ffc09ddc75629e1e5ced0cb717e06ee7d078d864 Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 20 Mar 2024 08:51:27 +0100 Subject: [PATCH 4/9] CI fix cleanup --- .github/workflows/buildReporting.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/buildReporting.yml b/.github/workflows/buildReporting.yml index 28f4759f..6739d0c8 100644 --- a/.github/workflows/buildReporting.yml +++ b/.github/workflows/buildReporting.yml @@ -149,9 +149,6 @@ jobs: TAGS: ${{ steps.meta.outputs.tags }} cleanup: - needs: docker-build - # Run only on tagging - if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') runs-on: ubuntu-latest steps: - From d3052dea879411b6a03b39bbea4abe06bd37d507 Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 20 Mar 2024 08:57:34 +0100 Subject: [PATCH 5/9] CI fix cleanup --- .github/workflows/buildReporting.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/buildReporting.yml b/.github/workflows/buildReporting.yml index 6739d0c8..843692ff 100644 --- a/.github/workflows/buildReporting.yml +++ b/.github/workflows/buildReporting.yml @@ -153,6 +153,6 @@ jobs: steps: - name: Delete Artifacts - uses: geekyeggo/delete-artifact@v4 + uses: geekyeggo/delete-artifact@v5 with: name: Package From 08af91cd49d3c078477d35a7cce86f0bab1764c2 Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 20 Mar 2024 09:01:47 +0100 Subject: [PATCH 6/9] CI fix cleanup --- .github/workflows/buildReporting.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/buildReporting.yml b/.github/workflows/buildReporting.yml index 843692ff..582f5876 100644 --- a/.github/workflows/buildReporting.yml +++ b/.github/workflows/buildReporting.yml @@ -149,6 +149,7 @@ jobs: TAGS: ${{ steps.meta.outputs.tags }} cleanup: + needs: [maven-build-reporting, docker-build] runs-on: ubuntu-latest steps: - From a4926054586052a901bb307a4a0083ad2b89f113 Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 20 Mar 2024 09:07:57 +0100 Subject: [PATCH 7/9] CI fix cleanup --- .github/workflows/buildReporting.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/buildReporting.yml b/.github/workflows/buildReporting.yml index 582f5876..73222563 100644 --- a/.github/workflows/buildReporting.yml +++ b/.github/workflows/buildReporting.yml @@ -150,6 +150,8 @@ jobs: cleanup: needs: [maven-build-reporting, docker-build] + if: | + always() runs-on: ubuntu-latest steps: - From 5008fbcd1936d95b710dd84cbc9339c552ef2ce5 Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 20 Mar 2024 11:00:25 +0100 Subject: [PATCH 8/9] SEBSERV-527 temporary fix --- .../sebconfig/impl/converter/RealNumberConverter.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/converter/RealNumberConverter.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/converter/RealNumberConverter.java index 982874b2..275ef83b 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/converter/RealNumberConverter.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/sebconfig/impl/converter/RealNumberConverter.java @@ -32,11 +32,12 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.sebconfig.AttributeValueCon @WebServiceProfile public class RealNumberConverter implements AttributeValueConverter { - private static final Logger log = LoggerFactory.getLogger(IntegerConverter.class); + private static final Logger log = LoggerFactory.getLogger(RealNumberConverter.class); public static final Set SUPPORTED_ATTR_NAMES = Utils.immutableSetOf( "defaultPageZoomLevel", - "defaultTextZoomLevel"); + "defaultTextZoomLevel", + "screenProctoringImageDownscale"); private static final String XML_TEMPLATE = "%s%s"; private static final String JSON_TEMPLATE = "\"%s\":%s"; @@ -89,6 +90,12 @@ public class RealNumberConverter implements AttributeValueConverter { realVal = 0; } + // NOTE: this is a special case for screenProctoringImageDownscale selector to get the selected real value + // from the selection-index instead using the index. See SEBSERV-527 + if ("screenProctoringImageDownscale".equals(attribute.name)) { + realVal = realVal / 10.0 + 1.0; + } + out.write(Utils.toByteArray(String.format( template, AttributeValueConverter.extractName(attribute), From b463e5be6c3835b7e7e470392b5f3a41e50af58e Mon Sep 17 00:00:00 2001 From: anhefti Date: Wed, 20 Mar 2024 11:30:48 +0100 Subject: [PATCH 9/9] SEBSERV-528 fixed --- .../seb/sebserver/gui/content/exam/ExamIndicatorsList.java | 3 +++ src/main/resources/messages.properties | 1 + 2 files changed, 4 insertions(+) diff --git a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamIndicatorsList.java b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamIndicatorsList.java index 599824b1..24b16f87 100644 --- a/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamIndicatorsList.java +++ b/src/main/java/ch/ethz/seb/sebserver/gui/content/exam/ExamIndicatorsList.java @@ -57,6 +57,8 @@ public class ExamIndicatorsList implements TemplateComposer { new LocTextKey("sebserver.exam.indicator.list.pleaseSelect"); private static final LocTextKey INDICATOR_EMPTY_LIST_MESSAGE = new LocTextKey("sebserver.exam.indicator.list.empty"); + private static final LocTextKey CONFIRM_MESSAGE_REMOVE_INDICATOR = + new LocTextKey("sebserver.exam.indicator.list.delete.confirm"); private final PageService pageService; private final ResourceService resourceService; @@ -144,6 +146,7 @@ public class ExamIndicatorsList implements TemplateComposer { indicatorTable::getMultiSelection, this::deleteSelectedIndicator, INDICATOR_EMPTY_SELECTION_TEXT_KEY) + .withConfirm(() -> CONFIRM_MESSAGE_REMOVE_INDICATOR) .publishIf(() -> indicatorEnabled && !isLight && editable && indicatorTable.hasAnyContent(), false) .newAction(ActionDefinition.EXAM_INDICATOR_NEW) diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 434fdaee..8de1f7bd 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -709,6 +709,7 @@ sebserver.exam.indicator.list.column.thresholds=Thresholds sebserver.exam.indicator.list.column.thresholds.tooltip=The thresholds of the indicator sebserver.exam.indicator.list.empty=There is currently no indicator defined for this exam. Please create a new one sebserver.exam.indicator.list.pleaseSelect=At first please select an indicator from the list +sebserver.exam.indicator.list.delete.confirm=Are you sure to delete the selected Indicator from the Exam? sebserver.exam.clientgroup.list.actions=  sebserver.exam.clientgroup.list.title=Client Groups