institutional logo implementation
This commit is contained in:
parent
6b8ef6c694
commit
64f10c6455
18 changed files with 412 additions and 195 deletions
|
@ -57,6 +57,8 @@ import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
@Order(6)
|
@Order(6)
|
||||||
public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements ErrorController {
|
public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements ErrorController {
|
||||||
|
|
||||||
|
@Value("${sebserver.webservice.api.admin.endpoint}")
|
||||||
|
private String adminEndpoint;
|
||||||
@Value("${sebserver.webservice.api.redirect.unauthorized}")
|
@Value("${sebserver.webservice.api.redirect.unauthorized}")
|
||||||
private String unauthorizedRedirect;
|
private String unauthorizedRedirect;
|
||||||
|
|
||||||
|
@ -82,7 +84,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements E
|
||||||
web
|
web
|
||||||
.ignoring()
|
.ignoring()
|
||||||
.antMatchers("/error")
|
.antMatchers("/error")
|
||||||
.antMatchers(API.LOGO_ENDPOINT + "/*");
|
.antMatchers(this.adminEndpoint + API.INFO_ENDPOINT + "/**");
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequestMapping("/error")
|
@RequestMapping("/error")
|
||||||
|
|
|
@ -10,6 +10,7 @@ package ch.ethz.seb.sebserver.gbl.api;
|
||||||
|
|
||||||
public final class API {
|
public final class API {
|
||||||
|
|
||||||
|
public static final String PARAM_LOGO_IMAGE = "logoImageBase64";
|
||||||
public static final String PARAM_INSTITUTION_ID = "institutionId";
|
public static final String PARAM_INSTITUTION_ID = "institutionId";
|
||||||
public static final String PARAM_MODEL_ID = "modelId";
|
public static final String PARAM_MODEL_ID = "modelId";
|
||||||
public static final String PARAM_ENTITY_TYPE = "entityType";
|
public static final String PARAM_ENTITY_TYPE = "entityType";
|
||||||
|
@ -17,8 +18,13 @@ public final class API {
|
||||||
public static final String INSTITUTION_VAR_PATH_SEGMENT = "/{" + PARAM_INSTITUTION_ID + "}";
|
public static final String INSTITUTION_VAR_PATH_SEGMENT = "/{" + PARAM_INSTITUTION_ID + "}";
|
||||||
public static final String MODEL_ID_VAR_PATH_SEGMENT = "/{" + PARAM_MODEL_ID + "}";
|
public static final String MODEL_ID_VAR_PATH_SEGMENT = "/{" + PARAM_MODEL_ID + "}";
|
||||||
|
|
||||||
public static final String LOGO_ENDPOINT = "/logo";
|
public static final String INFO_ENDPOINT = "/info";
|
||||||
public static final String INSTITUTIONAL_LOGO_PATH = LOGO_ENDPOINT + INSTITUTION_VAR_PATH_SEGMENT;
|
|
||||||
|
public static final String LOGO_PATH_SEGMENT = "/logo";
|
||||||
|
public static final String INSTITUTIONAL_LOGO_PATH = LOGO_PATH_SEGMENT + "/{urlSuffix}";
|
||||||
|
|
||||||
|
public static final String PRIVILEGES_PATH_SEGMENT = "/privileges";
|
||||||
|
public static final String PRIVILEGES_ENDPOINT = INFO_ENDPOINT + PRIVILEGES_PATH_SEGMENT;
|
||||||
|
|
||||||
public static final String INSTITUTION_ENDPOINT = "/institution";
|
public static final String INSTITUTION_ENDPOINT = "/institution";
|
||||||
|
|
||||||
|
|
|
@ -19,28 +19,28 @@ import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||||
public final class Privilege {
|
public final class Privilege {
|
||||||
|
|
||||||
/** The RoleTypeKey defining the UserRole and EntityType for this Privilege */
|
/** The RoleTypeKey defining the UserRole and EntityType for this Privilege */
|
||||||
@JsonProperty
|
@JsonProperty("roleTypeKey")
|
||||||
public final RoleTypeKey roleTypeKey;
|
public final RoleTypeKey roleTypeKey;
|
||||||
|
|
||||||
/** Defines a base-privilege type that defines the overall access for an entity-type */
|
/** Defines a base-privilege type that defines the overall access for an entity-type */
|
||||||
@JsonProperty
|
@JsonProperty("basePrivilege")
|
||||||
public final PrivilegeType basePrivilege;
|
public final PrivilegeType basePrivilege;
|
||||||
|
|
||||||
/** Defines an institutional privilege type that defines the institutional restricted access for a
|
/** Defines an institutional privilege type that defines the institutional restricted access for a
|
||||||
* entity-type */
|
* entity-type */
|
||||||
@JsonProperty
|
@JsonProperty("institutionalPrivilege")
|
||||||
public final PrivilegeType institutionalPrivilege;
|
public final PrivilegeType institutionalPrivilege;
|
||||||
|
|
||||||
/** Defines an ownership privilege type that defines the ownership restricted access for a entity-type */
|
/** Defines an ownership privilege type that defines the ownership restricted access for a entity-type */
|
||||||
@JsonProperty
|
@JsonProperty("ownershipPrivilege")
|
||||||
public final PrivilegeType ownershipPrivilege;
|
public final PrivilegeType ownershipPrivilege;
|
||||||
|
|
||||||
@JsonCreator
|
@JsonCreator
|
||||||
public Privilege(
|
public Privilege(
|
||||||
final RoleTypeKey roleTypeKey,
|
@JsonProperty("roleTypeKey") final RoleTypeKey roleTypeKey,
|
||||||
final PrivilegeType basePrivilege,
|
@JsonProperty("basePrivilege") final PrivilegeType basePrivilege,
|
||||||
final PrivilegeType institutionalPrivilege,
|
@JsonProperty("institutionalPrivilege") final PrivilegeType institutionalPrivilege,
|
||||||
final PrivilegeType ownershipPrivilege) {
|
@JsonProperty("ownershipPrivilege") final PrivilegeType ownershipPrivilege) {
|
||||||
|
|
||||||
this.roleTypeKey = roleTypeKey;
|
this.roleTypeKey = roleTypeKey;
|
||||||
this.basePrivilege = basePrivilege;
|
this.basePrivilege = basePrivilege;
|
||||||
|
@ -85,13 +85,16 @@ public final class Privilege {
|
||||||
/** A key that combines UserRole EntityType identity */
|
/** A key that combines UserRole EntityType identity */
|
||||||
public static final class RoleTypeKey {
|
public static final class RoleTypeKey {
|
||||||
|
|
||||||
@JsonProperty
|
@JsonProperty("entityType")
|
||||||
public final EntityType entityType;
|
public final EntityType entityType;
|
||||||
@JsonProperty
|
@JsonProperty("userRole")
|
||||||
public final UserRole userRole;
|
public final UserRole userRole;
|
||||||
|
|
||||||
@JsonCreator
|
@JsonCreator
|
||||||
public RoleTypeKey(final EntityType type, final UserRole role) {
|
public RoleTypeKey(
|
||||||
|
@JsonProperty("entityType") final EntityType type,
|
||||||
|
@JsonProperty("userRole") final UserRole role) {
|
||||||
|
|
||||||
this.entityType = type;
|
this.entityType = type;
|
||||||
this.userRole = role;
|
this.userRole = role;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,22 +8,13 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui;
|
package ch.ethz.seb.sebserver.gui;
|
||||||
|
|
||||||
import java.io.IOException;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.annotation.Order;
|
import org.springframework.core.annotation.Order;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
import org.springframework.security.config.annotation.web.builders.WebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
|
||||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
import org.springframework.security.web.util.matcher.OrRequestMatcher;
|
import org.springframework.security.web.util.matcher.OrRequestMatcher;
|
||||||
import org.springframework.security.web.util.matcher.RequestMatcher;
|
import org.springframework.security.web.util.matcher.RequestMatcher;
|
||||||
|
@ -35,10 +26,8 @@ import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
@Order(4)
|
@Order(4)
|
||||||
public class GuiWebsecurityConfig extends WebSecurityConfigurerAdapter {
|
public class GuiWebsecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
|
|
||||||
@Value("${sebserver.gui.entrypoint}")
|
@Autowired
|
||||||
private String guiEndpointPath;
|
private InstitutionalAuthenticationEntryPoint institutionalAuthenticationEntryPoint;
|
||||||
@Value("${sebserver.webservice.api.redirect.unauthorized}")
|
|
||||||
private String unauthorizedRedirect;
|
|
||||||
|
|
||||||
/** Gui-service related public URLS from spring web security perspective */
|
/** Gui-service related public URLS from spring web security perspective */
|
||||||
public static final RequestMatcher PUBLIC_URLS = new OrRequestMatcher(
|
public static final RequestMatcher PUBLIC_URLS = new OrRequestMatcher(
|
||||||
|
@ -67,19 +56,7 @@ public class GuiWebsecurityConfig extends WebSecurityConfigurerAdapter {
|
||||||
.authenticated()
|
.authenticated()
|
||||||
.and()
|
.and()
|
||||||
.exceptionHandling()
|
.exceptionHandling()
|
||||||
.authenticationEntryPoint(
|
.authenticationEntryPoint(this.institutionalAuthenticationEntryPoint)
|
||||||
new AuthenticationEntryPoint() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void commence(
|
|
||||||
final HttpServletRequest request,
|
|
||||||
final HttpServletResponse response,
|
|
||||||
final AuthenticationException authException) throws IOException, ServletException {
|
|
||||||
|
|
||||||
response.setStatus(HttpStatus.UNAUTHORIZED.value());
|
|
||||||
response.sendRedirect(GuiWebsecurityConfig.this.unauthorizedRedirect);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.and()
|
.and()
|
||||||
.formLogin().disable()
|
.formLogin().disable()
|
||||||
.httpBasic().disable()
|
.httpBasic().disable()
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.gui;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.servlet.RequestDispatcher;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.WebserviceURIService;
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Component
|
||||||
|
final class InstitutionalAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||||
|
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(InstitutionalAuthenticationEntryPoint.class);
|
||||||
|
|
||||||
|
private final String guiEntryPoint;
|
||||||
|
private final String guiRedirect;
|
||||||
|
private final WebserviceURIService webserviceURIService;
|
||||||
|
private final ClientHttpRequestFactory clientHttpRequestFactory;
|
||||||
|
|
||||||
|
protected InstitutionalAuthenticationEntryPoint(
|
||||||
|
@Value("${sebserver.gui.entrypoint}") final String guiEntryPoint,
|
||||||
|
@Value("${sebserver.webservice.api.redirect.unauthorized}") final String guiRedirect,
|
||||||
|
final WebserviceURIService webserviceURIService,
|
||||||
|
final ClientHttpRequestFactory clientHttpRequestFactory) {
|
||||||
|
|
||||||
|
this.guiEntryPoint = guiEntryPoint;
|
||||||
|
this.guiRedirect = guiRedirect;
|
||||||
|
this.webserviceURIService = webserviceURIService;
|
||||||
|
this.clientHttpRequestFactory = clientHttpRequestFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void commence(
|
||||||
|
final HttpServletRequest request,
|
||||||
|
final HttpServletResponse response,
|
||||||
|
final AuthenticationException authException) throws IOException, ServletException {
|
||||||
|
|
||||||
|
final String requestURI = request.getRequestURI();
|
||||||
|
|
||||||
|
log.info("No default gui entrypoint requested: {}", requestURI);
|
||||||
|
|
||||||
|
final String logoImageBase64 = requestLogoImage(requestURI);
|
||||||
|
if (StringUtils.isNoneBlank(logoImageBase64)) {
|
||||||
|
// forward
|
||||||
|
request.getSession().setAttribute(API.PARAM_LOGO_IMAGE, logoImageBase64);
|
||||||
|
final RequestDispatcher dispatcher = request.getServletContext()
|
||||||
|
.getRequestDispatcher(this.guiEntryPoint);
|
||||||
|
dispatcher.forward(request, response);
|
||||||
|
// redirect
|
||||||
|
} else {
|
||||||
|
request.getSession().removeAttribute(API.PARAM_LOGO_IMAGE);
|
||||||
|
response.setStatus(HttpStatus.UNAUTHORIZED.value());
|
||||||
|
response.sendRedirect(this.guiRedirect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String requestLogoImage(final String requestURI) {
|
||||||
|
log.debug("Trying to verify insitution from requested entrypoint url: {}", requestURI);
|
||||||
|
try {
|
||||||
|
|
||||||
|
final RestTemplate restTemplate = new RestTemplate();
|
||||||
|
restTemplate.setRequestFactory(this.clientHttpRequestFactory);
|
||||||
|
|
||||||
|
final ResponseEntity<String> exchange = restTemplate
|
||||||
|
.exchange(
|
||||||
|
this.webserviceURIService.getURIBuilder()
|
||||||
|
.path(API.INFO_ENDPOINT + API.INSTITUTIONAL_LOGO_PATH)
|
||||||
|
.toUriString(),
|
||||||
|
HttpMethod.GET,
|
||||||
|
HttpEntity.EMPTY,
|
||||||
|
String.class,
|
||||||
|
requestURI.replaceAll("/", ""));
|
||||||
|
|
||||||
|
if (exchange.getStatusCodeValue() == HttpStatus.OK.value()) {
|
||||||
|
return exchange.getBody();
|
||||||
|
} else {
|
||||||
|
log.error("Failed to verify insitution from requested entrypoint url: {}, response: {}", requestURI,
|
||||||
|
exchange);
|
||||||
|
}
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Failed to verify insitution from requested entrypoint url: {}", requestURI, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,7 +14,6 @@ import java.util.Map;
|
||||||
import javax.servlet.ServletContext;
|
import javax.servlet.ServletContext;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.rap.rwt.application.AbstractEntryPoint;
|
import org.eclipse.rap.rwt.application.AbstractEntryPoint;
|
||||||
import org.eclipse.rap.rwt.application.Application;
|
import org.eclipse.rap.rwt.application.Application;
|
||||||
|
@ -22,14 +21,12 @@ import org.eclipse.rap.rwt.application.ApplicationConfiguration;
|
||||||
import org.eclipse.rap.rwt.application.EntryPoint;
|
import org.eclipse.rap.rwt.application.EntryPoint;
|
||||||
import org.eclipse.rap.rwt.application.EntryPointFactory;
|
import org.eclipse.rap.rwt.application.EntryPointFactory;
|
||||||
import org.eclipse.rap.rwt.client.WebClient;
|
import org.eclipse.rap.rwt.client.WebClient;
|
||||||
import org.eclipse.rap.rwt.client.service.StartupParameters;
|
|
||||||
import org.eclipse.swt.widgets.Composite;
|
import org.eclipse.swt.widgets.Composite;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.SEBServerAuthorizationContext;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.SEBServerAuthorizationContext;
|
||||||
|
|
||||||
|
@ -100,19 +97,6 @@ public class RAPConfiguration implements ApplicationConfiguration {
|
||||||
final HttpSession httpSession,
|
final HttpSession httpSession,
|
||||||
final WebApplicationContext webApplicationContext) {
|
final WebApplicationContext webApplicationContext) {
|
||||||
|
|
||||||
// NOTE: if the user comes from a specified institutional login url (redirect from server) the institutionId is get from
|
|
||||||
// request and put to the session attributes. The institutionId can later be used for institution specific login page
|
|
||||||
// look and feel as well as for sending the institutionId within the login credentials to give the authorization service
|
|
||||||
// some restriction to search the user. This is especially useful if the user is external registered and verified
|
|
||||||
// with LDAP or AAI SAML
|
|
||||||
final StartupParameters reqParams = RWT.getClient().getService(StartupParameters.class);
|
|
||||||
final String institutionId = reqParams.getParameter(API.PARAM_INSTITUTION_ID);
|
|
||||||
if (StringUtils.isNotBlank(institutionId)) {
|
|
||||||
httpSession.setAttribute(API.PARAM_INSTITUTION_ID, institutionId);
|
|
||||||
} else {
|
|
||||||
httpSession.removeAttribute(API.PARAM_INSTITUTION_ID);
|
|
||||||
}
|
|
||||||
|
|
||||||
final AuthorizationContextHolder authorizationContextHolder = webApplicationContext
|
final AuthorizationContextHolder authorizationContextHolder = webApplicationContext
|
||||||
.getBean(AuthorizationContextHolder.class);
|
.getBean(AuthorizationContextHolder.class);
|
||||||
final SEBServerAuthorizationContext authorizationContext = authorizationContextHolder
|
final SEBServerAuthorizationContext authorizationContext = authorizationContextHolder
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.authorization.PrivilegeType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
import ch.ethz.seb.sebserver.gbl.model.Domain;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
import ch.ethz.seb.sebserver.gbl.model.Entity;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
import ch.ethz.seb.sebserver.gbl.model.institution.Institution;
|
||||||
|
@ -37,6 +38,7 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitution;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.NewInstitution;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.NewInstitution;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.SaveInstitution;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.SaveInstitution;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
|
@ -46,10 +48,16 @@ public class InstitutionForm implements TemplateComposer {
|
||||||
|
|
||||||
private final PageFormService pageFormService;
|
private final PageFormService pageFormService;
|
||||||
private final RestService restService;
|
private final RestService restService;
|
||||||
|
private final CurrentUser currentUser;
|
||||||
|
|
||||||
|
protected InstitutionForm(
|
||||||
|
final PageFormService pageFormService,
|
||||||
|
final RestService restService,
|
||||||
|
final CurrentUser currentUser) {
|
||||||
|
|
||||||
protected InstitutionForm(final PageFormService pageFormService, final RestService restService) {
|
|
||||||
this.pageFormService = pageFormService;
|
this.pageFormService = pageFormService;
|
||||||
this.restService = restService;
|
this.restService = restService;
|
||||||
|
this.currentUser = currentUser;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -93,7 +101,7 @@ public class InstitutionForm implements TemplateComposer {
|
||||||
content.setLayout(contentLayout);
|
content.setLayout(contentLayout);
|
||||||
content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
||||||
|
|
||||||
// title
|
// title (interactive9
|
||||||
final Label pageTitle = widgetFactory.labelLocalizedTitle(
|
final Label pageTitle = widgetFactory.labelLocalizedTitle(
|
||||||
content, new LocTextKey(
|
content, new LocTextKey(
|
||||||
"sebserver.institution.form.title",
|
"sebserver.institution.form.title",
|
||||||
|
@ -141,10 +149,13 @@ public class InstitutionForm implements TemplateComposer {
|
||||||
|
|
||||||
// propagate content actions to action-pane
|
// propagate content actions to action-pane
|
||||||
if (readonly) {
|
if (readonly) {
|
||||||
|
if (this.currentUser.hasPrivilege(PrivilegeType.WRITE, institution)) {
|
||||||
formContext.createAction(ActionDefinition.INSTITUTION_NEW)
|
formContext.createAction(ActionDefinition.INSTITUTION_NEW)
|
||||||
.withExec(InstitutionActions::newInstitution)
|
.withExec(InstitutionActions::newInstitution)
|
||||||
.publish()
|
.publish();
|
||||||
.createAction(ActionDefinition.INSTITUTION_MODIFY)
|
}
|
||||||
|
if (this.currentUser.hasPrivilege(PrivilegeType.MODIFY, institution)) {
|
||||||
|
formContext.createAction(ActionDefinition.INSTITUTION_MODIFY)
|
||||||
.withExec(InstitutionActions::editInstitution)
|
.withExec(InstitutionActions::editInstitution)
|
||||||
.publish();
|
.publish();
|
||||||
if (!institution.isActive()) {
|
if (!institution.isActive()) {
|
||||||
|
@ -156,6 +167,7 @@ public class InstitutionForm implements TemplateComposer {
|
||||||
.withExec(InstitutionActions::deactivateInstitution)
|
.withExec(InstitutionActions::deactivateInstitution)
|
||||||
.publish();
|
.publish();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
formContext.createAction(ActionDefinition.INSTITUTION_SAVE)
|
formContext.createAction(ActionDefinition.INSTITUTION_SAVE)
|
||||||
.withExec(formHandle::postChanges)
|
.withExec(formHandle::postChanges)
|
||||||
|
@ -164,7 +176,6 @@ public class InstitutionForm implements TemplateComposer {
|
||||||
.withExec(InstitutionActions::cancelEditInstitution)
|
.withExec(InstitutionActions::cancelEditInstitution)
|
||||||
.withConfirm("sebserver.overall.action.modify.cancel.confirm")
|
.withConfirm("sebserver.overall.action.modify.cancel.confirm")
|
||||||
.publish();
|
.publish();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import java.io.ByteArrayInputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64InputStream;
|
import org.apache.commons.codec.binary.Base64InputStream;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.eclipse.rap.rwt.RWT;
|
import org.eclipse.rap.rwt.RWT;
|
||||||
import org.eclipse.swt.SWT;
|
import org.eclipse.swt.SWT;
|
||||||
import org.eclipse.swt.graphics.Image;
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
@ -27,7 +28,6 @@ import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.client.RestTemplate;
|
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
|
||||||
|
@ -36,7 +36,6 @@ import ch.ethz.seb.sebserver.gui.service.page.PageContext;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
import ch.ethz.seb.sebserver.gui.service.page.PageContext.AttributeKeys;
|
||||||
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
import ch.ethz.seb.sebserver.gui.service.page.TemplateComposer;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.WebserviceURIService;
|
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.Message;
|
import ch.ethz.seb.sebserver.gui.service.widget.Message;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory;
|
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory;
|
||||||
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory.CustomVariant;
|
import ch.ethz.seb.sebserver.gui.service.widget.WidgetFactory.CustomVariant;
|
||||||
|
@ -47,20 +46,17 @@ public class DefaultPageLayout implements TemplateComposer {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(DefaultPageLayout.class);
|
private static final Logger log = LoggerFactory.getLogger(DefaultPageLayout.class);
|
||||||
|
|
||||||
private final WebserviceURIService webserviceURIService;
|
|
||||||
private final WidgetFactory widgetFactory;
|
private final WidgetFactory widgetFactory;
|
||||||
private final PolyglotPageService polyglotPageService;
|
private final PolyglotPageService polyglotPageService;
|
||||||
private final AuthorizationContextHolder authorizationContextHolder;
|
private final AuthorizationContextHolder authorizationContextHolder;
|
||||||
private final String sebServerVersion;
|
private final String sebServerVersion;
|
||||||
|
|
||||||
public DefaultPageLayout(
|
public DefaultPageLayout(
|
||||||
final WebserviceURIService webserviceURIService,
|
|
||||||
final WidgetFactory widgetFactory,
|
final WidgetFactory widgetFactory,
|
||||||
final PolyglotPageService polyglotPageService,
|
final PolyglotPageService polyglotPageService,
|
||||||
final AuthorizationContextHolder authorizationContextHolder,
|
final AuthorizationContextHolder authorizationContextHolder,
|
||||||
@Value("${sebserver.version}") final String sebServerVersion) {
|
@Value("${sebserver.version}") final String sebServerVersion) {
|
||||||
|
|
||||||
this.webserviceURIService = webserviceURIService;
|
|
||||||
this.widgetFactory = widgetFactory;
|
this.widgetFactory = widgetFactory;
|
||||||
this.polyglotPageService = polyglotPageService;
|
this.polyglotPageService = polyglotPageService;
|
||||||
this.authorizationContextHolder = authorizationContextHolder;
|
this.authorizationContextHolder = authorizationContextHolder;
|
||||||
|
@ -173,28 +169,7 @@ public class DefaultPageLayout implements TemplateComposer {
|
||||||
logo.setLayoutData(logoCell);
|
logo.setLayoutData(logoCell);
|
||||||
|
|
||||||
// try to get institutional logo first. If no success, use default logo
|
// try to get institutional logo first. If no success, use default logo
|
||||||
try {
|
loadInstitutionalLogo(pageContext, logo);
|
||||||
final String institutionId = (String) RWT.getUISession()
|
|
||||||
.getHttpSession()
|
|
||||||
.getAttribute(API.PARAM_INSTITUTION_ID);
|
|
||||||
|
|
||||||
final String logoBase64 = new RestTemplate()
|
|
||||||
.getForObject(
|
|
||||||
this.webserviceURIService.getWebserviceServerAddress() + API.INSTITUTIONAL_LOGO_PATH,
|
|
||||||
String.class,
|
|
||||||
institutionId);
|
|
||||||
|
|
||||||
final Base64InputStream input = new Base64InputStream(
|
|
||||||
new ByteArrayInputStream(logoBase64.getBytes(StandardCharsets.UTF_8)),
|
|
||||||
false);
|
|
||||||
|
|
||||||
logo.setData(RWT.CUSTOM_VARIANT, "bgLogoNoImage");
|
|
||||||
logo.setBackgroundImage(new Image(pageContext.getShell().getDisplay(), input));
|
|
||||||
|
|
||||||
} catch (final Exception e) {
|
|
||||||
log.warn("Get institutional logo failed: {}", e.getMessage());
|
|
||||||
logo.setData(RWT.CUSTOM_VARIANT, "bgLogo");
|
|
||||||
}
|
|
||||||
|
|
||||||
final Composite langSupport = new Composite(logoBar, SWT.NONE);
|
final Composite langSupport = new Composite(logoBar, SWT.NONE);
|
||||||
final GridData langSupportCell = new GridData(SWT.RIGHT, SWT.CENTER, false, false);
|
final GridData langSupportCell = new GridData(SWT.RIGHT, SWT.CENTER, false, false);
|
||||||
|
@ -208,14 +183,6 @@ public class DefaultPageLayout implements TemplateComposer {
|
||||||
langSupport.setLayout(rowLayout);
|
langSupport.setLayout(rowLayout);
|
||||||
|
|
||||||
this.widgetFactory.createLanguageSelector(pageContext.copyOf(langSupport));
|
this.widgetFactory.createLanguageSelector(pageContext.copyOf(langSupport));
|
||||||
// for (final Locale locale : this.i18nSupport.supportedLanguages()) {
|
|
||||||
// final LanguageSelection languageSelection = new LanguageSelection(langSupport, locale);
|
|
||||||
// languageSelection.updateLocale(this.i18nSupport);
|
|
||||||
// languageSelection.addListener(SWT.MouseDown, event -> {
|
|
||||||
// this.polyglotPageService.setPageLocale(pageContext.root, languageSelection.locale);
|
|
||||||
//
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void composeContent(final PageContext pageContext) {
|
private void composeContent(final PageContext pageContext) {
|
||||||
|
@ -305,25 +272,28 @@ public class DefaultPageLayout implements TemplateComposer {
|
||||||
new LocTextKey("sebserver.overall.version", this.sebServerVersion));
|
new LocTextKey("sebserver.overall.version", this.sebServerVersion));
|
||||||
}
|
}
|
||||||
|
|
||||||
// private final class LanguageSelection extends Label implements Polyglot {
|
private void loadInstitutionalLogo(final PageContext pageContext, final Composite logo) {
|
||||||
//
|
logo.setData(RWT.CUSTOM_VARIANT, "bgLogo");
|
||||||
// private static final long serialVersionUID = 8110167162843383940L;
|
try {
|
||||||
// private final Locale locale;
|
|
||||||
//
|
final String imageBase64 = (String) RWT.getUISession()
|
||||||
// public LanguageSelection(final Composite parent, final Locale locale) {
|
.getHttpSession()
|
||||||
// super(parent, SWT.NONE);
|
.getAttribute(API.PARAM_LOGO_IMAGE);
|
||||||
// this.locale = locale;
|
|
||||||
// super.setData(RWT.CUSTOM_VARIANT, "header");
|
if (StringUtils.isBlank(imageBase64)) {
|
||||||
// super.setText("| " + locale.getLanguage().toUpperCase());
|
return;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// @Override
|
final Base64InputStream input = new Base64InputStream(
|
||||||
// public void updateLocale(final I18nSupport i18nSupport) {
|
new ByteArrayInputStream(imageBase64.getBytes(StandardCharsets.UTF_8)),
|
||||||
// super.setVisible(
|
false);
|
||||||
// !i18nSupport.getCurrentLocale()
|
|
||||||
// .getLanguage()
|
logo.setData(RWT.CUSTOM_VARIANT, "bgLogoNoImage");
|
||||||
// .equals(this.locale.getLanguage()));
|
logo.setBackgroundImage(new Image(pageContext.getShell().getDisplay(), input));
|
||||||
// }
|
|
||||||
// }
|
} catch (final Exception e) {
|
||||||
|
log.warn("Get institutional logo failed: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,12 +33,12 @@ public class RestService {
|
||||||
|
|
||||||
public RestService(
|
public RestService(
|
||||||
final AuthorizationContextHolder authorizationContextHolder,
|
final AuthorizationContextHolder authorizationContextHolder,
|
||||||
final WebserviceURIService webserviceURIBuilderSupplier,
|
|
||||||
final JSONMapper jsonMapper,
|
final JSONMapper jsonMapper,
|
||||||
final Collection<RestCall<?>> calls) {
|
final Collection<RestCall<?>> calls) {
|
||||||
|
|
||||||
this.authorizationContextHolder = authorizationContextHolder;
|
this.authorizationContextHolder = authorizationContextHolder;
|
||||||
this.webserviceURIBuilderSupplier = webserviceURIBuilderSupplier;
|
this.webserviceURIBuilderSupplier = authorizationContextHolder
|
||||||
|
.getWebserviceURIService();
|
||||||
|
|
||||||
this.calls = calls
|
this.calls = calls
|
||||||
.stream()
|
.stream()
|
||||||
|
@ -54,7 +54,7 @@ public class RestService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public UriComponentsBuilder getWebserviceURIBuilder() {
|
public UriComponentsBuilder getWebserviceURIBuilder() {
|
||||||
return this.webserviceURIBuilderSupplier.getBuilder();
|
return this.webserviceURIBuilderSupplier.getURIBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
|
|
@ -16,8 +16,11 @@ public interface AuthorizationContextHolder {
|
||||||
|
|
||||||
SEBServerAuthorizationContext getAuthorizationContext(HttpSession session);
|
SEBServerAuthorizationContext getAuthorizationContext(HttpSession session);
|
||||||
|
|
||||||
|
WebserviceURIService getWebserviceURIService();
|
||||||
|
|
||||||
// TODO error handling!?
|
// TODO error handling!?
|
||||||
default SEBServerAuthorizationContext getAuthorizationContext() {
|
default SEBServerAuthorizationContext getAuthorizationContext() {
|
||||||
return getAuthorizationContext(RWT.getUISession().getHttpSession());
|
return getAuthorizationContext(RWT.getUISession().getHttpSession());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,17 +8,33 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.gui.service.remote.webservice.auth;
|
package ch.ethz.seb.sebserver.gui.service.remote.webservice.auth;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
import org.springframework.context.annotation.ScopedProxyMode;
|
import org.springframework.context.annotation.ScopedProxyMode;
|
||||||
|
import org.springframework.core.ParameterizedTypeReference;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.authorization.Privilege;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.authorization.Privilege.RoleTypeKey;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.authorization.PrivilegeType;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantEntity;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
|
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||||
|
@ -29,6 +45,7 @@ public class CurrentUser {
|
||||||
|
|
||||||
private final AuthorizationContextHolder authorizationContextHolder;
|
private final AuthorizationContextHolder authorizationContextHolder;
|
||||||
private SEBServerAuthorizationContext authContext = null;
|
private SEBServerAuthorizationContext authContext = null;
|
||||||
|
private Map<RoleTypeKey, Privilege> privileges = null;
|
||||||
|
|
||||||
public CurrentUser(final AuthorizationContextHolder authorizationContextHolder) {
|
public CurrentUser(final AuthorizationContextHolder authorizationContextHolder) {
|
||||||
this.authorizationContextHolder = authorizationContextHolder;
|
this.authorizationContextHolder = authorizationContextHolder;
|
||||||
|
@ -58,6 +75,64 @@ public class CurrentUser {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasPrivilege(final PrivilegeType privilegeType, final EntityType entityType) {
|
||||||
|
if (loadPrivileges()) {
|
||||||
|
try {
|
||||||
|
return get().getRoles()
|
||||||
|
.stream()
|
||||||
|
.map(roleName -> UserRole.valueOf(roleName))
|
||||||
|
.map(role -> new RoleTypeKey(entityType, role))
|
||||||
|
.map(key -> this.privileges.get(key))
|
||||||
|
.filter(checkPrivilege(get(), privilegeType, null))
|
||||||
|
.findFirst()
|
||||||
|
.isPresent();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Failed to verify privilege: PrivilegeType {} EntityType {}",
|
||||||
|
privilegeType, entityType, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasPrivilege(
|
||||||
|
final PrivilegeType privilegeType,
|
||||||
|
final GrantEntity grantEntity) {
|
||||||
|
|
||||||
|
if (loadPrivileges()) {
|
||||||
|
final EntityType entityType = grantEntity.entityType();
|
||||||
|
try {
|
||||||
|
return get().getRoles()
|
||||||
|
.stream()
|
||||||
|
.map(roleName -> UserRole.valueOf(roleName))
|
||||||
|
.map(role -> new RoleTypeKey(entityType, role))
|
||||||
|
.map(key -> this.privileges.get(key))
|
||||||
|
.filter(checkPrivilege(get(), privilegeType, grantEntity))
|
||||||
|
.findFirst()
|
||||||
|
.isPresent();
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Failed to verify privilege: PrivilegeType {} EntityType {}",
|
||||||
|
privilegeType, entityType, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Predicate<Privilege> checkPrivilege(
|
||||||
|
final UserInfo userInfo,
|
||||||
|
final PrivilegeType privilegeType,
|
||||||
|
final GrantEntity grantEntity) {
|
||||||
|
|
||||||
|
return priv -> priv.hasBasePrivilege(privilegeType)
|
||||||
|
|| ((grantEntity != null) &&
|
||||||
|
(priv.hasInstitutionalPrivilege(privilegeType)
|
||||||
|
&& get().institutionId.longValue() == grantEntity.getInstitutionId()
|
||||||
|
.longValue())
|
||||||
|
|| (priv.hasOwnershipPrivilege(privilegeType)
|
||||||
|
&& get().uuid.equals(grantEntity.getOwnerId())));
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isAvailable() {
|
public boolean isAvailable() {
|
||||||
updateContext();
|
updateContext();
|
||||||
return this.authContext != null && this.authContext.isLoggedIn();
|
return this.authContext != null && this.authContext.isLoggedIn();
|
||||||
|
@ -69,4 +144,52 @@ public class CurrentUser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean loadPrivileges() {
|
||||||
|
if (this.privileges != null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateContext();
|
||||||
|
if (this.authContext != null) {
|
||||||
|
try {
|
||||||
|
final WebserviceURIService webserviceURIService =
|
||||||
|
this.authorizationContextHolder.getWebserviceURIService();
|
||||||
|
final ResponseEntity<Collection<Privilege>> exchange = this.authContext.getRestTemplate()
|
||||||
|
.exchange(
|
||||||
|
webserviceURIService.getURIBuilder()
|
||||||
|
.path(API.PRIVILEGES_ENDPOINT)
|
||||||
|
.toUriString(),
|
||||||
|
HttpMethod.GET,
|
||||||
|
HttpEntity.EMPTY,
|
||||||
|
new ParameterizedTypeReference<Collection<Privilege>>() {
|
||||||
|
});
|
||||||
|
|
||||||
|
if (exchange.getStatusCodeValue() == HttpStatus.OK.value()) {
|
||||||
|
this.privileges = exchange.getBody().stream()
|
||||||
|
.reduce(new HashMap<RoleTypeKey, Privilege>(),
|
||||||
|
(map, priv) -> {
|
||||||
|
map.put(priv.roleTypeKey, priv);
|
||||||
|
return map;
|
||||||
|
},
|
||||||
|
(map1, map2) -> {
|
||||||
|
map1.putAll(map2);
|
||||||
|
return map1;
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
log.error("Failed to get Privileges from webservice API: {}", exchange);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (final Exception e) {
|
||||||
|
log.error("Failed to get Privileges from webservice API: ", e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.error("Failed to get Privileges from webservice API. No AuthorizationContext available");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,11 @@ public class OAuth2AuthorizationContextHolder implements AuthorizationContextHol
|
||||||
this.clientHttpRequestFactory = clientHttpRequestFactory;
|
this.clientHttpRequestFactory = clientHttpRequestFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WebserviceURIService getWebserviceURIService() {
|
||||||
|
return this.webserviceURIService;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SEBServerAuthorizationContext getAuthorizationContext(final HttpSession session) {
|
public SEBServerAuthorizationContext getAuthorizationContext(final HttpSession session) {
|
||||||
log.debug("Trying to get OAuth2AuthorizationContext from HttpSession: {}", session.getId());
|
log.debug("Trying to get OAuth2AuthorizationContext from HttpSession: {}", session.getId());
|
||||||
|
|
|
@ -43,7 +43,7 @@ public class WebserviceURIService {
|
||||||
return this.webserviceServerAddress;
|
return this.webserviceServerAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UriComponentsBuilder getBuilder() {
|
public UriComponentsBuilder getURIBuilder() {
|
||||||
return this.webserviceURIBuilder.cloneBuilder();
|
return this.webserviceURIBuilder.cloneBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ public class WebserviceURIService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCurrentUserRequestURI() {
|
public String getCurrentUserRequestURI() {
|
||||||
return getBuilder()
|
return getURIBuilder()
|
||||||
.path(CURRENT_USER_URI_PATH)
|
.path(CURRENT_USER_URI_PATH)
|
||||||
.toUriString();
|
.toUriString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,10 @@
|
||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.authorization;
|
package ch.ethz.seb.sebserver.webservice.servicelayer.authorization;
|
||||||
|
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.authorization.Privilege;
|
||||||
import ch.ethz.seb.sebserver.gbl.authorization.PrivilegeType;
|
import ch.ethz.seb.sebserver.gbl.authorization.PrivilegeType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityType;
|
import ch.ethz.seb.sebserver.gbl.model.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
|
@ -27,6 +29,11 @@ public interface AuthorizationGrantService {
|
||||||
* @return the UserService that is bundled within the AuthorizationGrantService */
|
* @return the UserService that is bundled within the AuthorizationGrantService */
|
||||||
UserService getUserService();
|
UserService getUserService();
|
||||||
|
|
||||||
|
/** All Privileges in a collection.
|
||||||
|
*
|
||||||
|
* @return all registered Privileges */
|
||||||
|
Collection<Privilege> getAllPrivileges();
|
||||||
|
|
||||||
/** Checks if the current user has any privilege (base or institutional or owner) for the given EntityType and
|
/** Checks if the current user has any privilege (base or institutional or owner) for the given EntityType and
|
||||||
* PrivilegeType.
|
* PrivilegeType.
|
||||||
*
|
*
|
||||||
|
|
|
@ -10,6 +10,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.authorization;
|
||||||
|
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -21,8 +22,8 @@ import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.authorization.Privilege;
|
import ch.ethz.seb.sebserver.gbl.authorization.Privilege;
|
||||||
import ch.ethz.seb.sebserver.gbl.authorization.PrivilegeType;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.authorization.Privilege.RoleTypeKey;
|
import ch.ethz.seb.sebserver.gbl.authorization.Privilege.RoleTypeKey;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.authorization.PrivilegeType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityType;
|
import ch.ethz.seb.sebserver.gbl.model.EntityType;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
|
@ -34,7 +35,7 @@ import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
public class AuthorizationGrantServiceImpl implements AuthorizationGrantService {
|
public class AuthorizationGrantServiceImpl implements AuthorizationGrantService {
|
||||||
|
|
||||||
/** Map of role based grants for specified entity types. */
|
/** Map of role based grants for specified entity types. */
|
||||||
private final Map<Privilege.RoleTypeKey, Privilege> grants = new HashMap<>();
|
private final Map<Privilege.RoleTypeKey, Privilege> privileges = new HashMap<>();
|
||||||
/** Map of collected AuthorizationGrantRule exceptions */
|
/** Map of collected AuthorizationGrantRule exceptions */
|
||||||
private final Map<EntityType, AuthorizationGrantRule> exceptionalRules =
|
private final Map<EntityType, AuthorizationGrantRule> exceptionalRules =
|
||||||
new EnumMap<>(EntityType.class);
|
new EnumMap<>(EntityType.class);
|
||||||
|
@ -58,6 +59,11 @@ public class AuthorizationGrantServiceImpl implements AuthorizationGrantService
|
||||||
return this.userService;
|
return this.userService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Privilege> getAllPrivileges() {
|
||||||
|
return Collections.unmodifiableCollection(this.privileges.values());
|
||||||
|
}
|
||||||
|
|
||||||
/** Initialize the (hard-coded) grants */
|
/** Initialize the (hard-coded) grants */
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
|
@ -200,7 +206,7 @@ public class AuthorizationGrantServiceImpl implements AuthorizationGrantService
|
||||||
final SEBServerUser user) {
|
final SEBServerUser user) {
|
||||||
|
|
||||||
for (final UserRole role : user.getUserRoles()) {
|
for (final UserRole role : user.getUserRoles()) {
|
||||||
final Privilege roleTypeGrant = this.grants.get(new RoleTypeKey(entityType, role));
|
final Privilege roleTypeGrant = this.privileges.get(new RoleTypeKey(entityType, role));
|
||||||
if (roleTypeGrant != null && roleTypeGrant.hasBasePrivilege(privilegeType)) {
|
if (roleTypeGrant != null && roleTypeGrant.hasBasePrivilege(privilegeType)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -238,7 +244,7 @@ public class AuthorizationGrantServiceImpl implements AuthorizationGrantService
|
||||||
final SEBServerUser user) {
|
final SEBServerUser user) {
|
||||||
|
|
||||||
for (final UserRole role : user.getUserRoles()) {
|
for (final UserRole role : user.getUserRoles()) {
|
||||||
final Privilege roleTypeGrant = this.grants.get(new RoleTypeKey(entityType, role));
|
final Privilege roleTypeGrant = this.privileges.get(new RoleTypeKey(entityType, role));
|
||||||
if (roleTypeGrant != null && roleTypeGrant.hasInstitutionalPrivilege(privilegeType)) {
|
if (roleTypeGrant != null && roleTypeGrant.hasInstitutionalPrivilege(privilegeType)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -328,7 +334,7 @@ public class AuthorizationGrantServiceImpl implements AuthorizationGrantService
|
||||||
this.grants = new EnumMap<>(UserRole.class);
|
this.grants = new EnumMap<>(UserRole.class);
|
||||||
for (final UserRole role : UserRole.values()) {
|
for (final UserRole role : UserRole.values()) {
|
||||||
this.grants.put(role,
|
this.grants.put(role,
|
||||||
service.grants.get(new RoleTypeKey(type, role)));
|
service.privileges.get(new RoleTypeKey(type, role)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -437,7 +443,7 @@ public class AuthorizationGrantServiceImpl implements AuthorizationGrantService
|
||||||
this.institutionalPrivilege,
|
this.institutionalPrivilege,
|
||||||
this.ownerPrivilege);
|
this.ownerPrivilege);
|
||||||
|
|
||||||
AuthorizationGrantServiceImpl.this.grants.put(roleTypeKey, roleTypeGrant);
|
AuthorizationGrantServiceImpl.this.privileges.put(roleTypeKey, roleTypeGrant);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.webservice.weblayer.api;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.authorization.Privilege;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationGrantService;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.InstitutionDAO;
|
||||||
|
|
||||||
|
@WebServiceProfile
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/${sebserver.webservice.api.admin.endpoint}" + API.INFO_ENDPOINT)
|
||||||
|
public class InfoController {
|
||||||
|
|
||||||
|
private final InstitutionDAO institutionDAO;
|
||||||
|
private final AuthorizationGrantService authorizationGrantService;
|
||||||
|
|
||||||
|
protected InfoController(
|
||||||
|
final InstitutionDAO institutionDAO,
|
||||||
|
final AuthorizationGrantService authorizationGrantService) {
|
||||||
|
|
||||||
|
this.institutionDAO = institutionDAO;
|
||||||
|
this.authorizationGrantService = authorizationGrantService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(
|
||||||
|
path = API.INSTITUTIONAL_LOGO_PATH,
|
||||||
|
method = RequestMethod.GET,
|
||||||
|
produces = MediaType.IMAGE_PNG_VALUE + ";base64")
|
||||||
|
public String logo(@PathVariable final String urlSuffix) {
|
||||||
|
return this.institutionDAO
|
||||||
|
.all(null, true)
|
||||||
|
.getOrThrow()
|
||||||
|
.stream()
|
||||||
|
.filter(inst -> urlSuffix.endsWith(inst.urlSuffix))
|
||||||
|
.findFirst()
|
||||||
|
.map(inst -> inst.logoImage)
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(
|
||||||
|
path = API.PRIVILEGES_PATH_SEGMENT,
|
||||||
|
method = RequestMethod.GET,
|
||||||
|
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||||
|
public Collection<Privilege> privileges() {
|
||||||
|
return this.authorizationGrantService.getAllPrivileges();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,38 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.webservice.weblayer.api;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.InstitutionDAO;
|
|
||||||
|
|
||||||
@WebServiceProfile
|
|
||||||
@RestController
|
|
||||||
public class LogoController {
|
|
||||||
|
|
||||||
private final InstitutionDAO institutionDAO;
|
|
||||||
|
|
||||||
protected LogoController(final InstitutionDAO institutionDAO) {
|
|
||||||
this.institutionDAO = institutionDAO;
|
|
||||||
}
|
|
||||||
|
|
||||||
@RequestMapping(API.INSTITUTIONAL_LOGO_PATH)
|
|
||||||
public String logo(@PathVariable final String institutionId) throws IOException {
|
|
||||||
return this.institutionDAO
|
|
||||||
.byModelId(institutionId)
|
|
||||||
.getOrThrow().logoImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.webservice.weblayer.api;
|
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
|
||||||
|
|
||||||
@WebServiceProfile
|
|
||||||
@RestController
|
|
||||||
public class PrivilegesController {
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue