fixed institutional logo handling

This commit is contained in:
anhefti 2019-08-08 20:35:57 +02:00
parent c97a2ff02b
commit 00d7a91a43
8 changed files with 100 additions and 20 deletions

View file

@ -45,6 +45,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.filter.CharacterEncodingFilter; import org.springframework.web.filter.CharacterEncodingFilter;
import ch.ethz.seb.sebserver.gbl.api.API;
import ch.ethz.seb.sebserver.gbl.profile.DevGuiProfile; import ch.ethz.seb.sebserver.gbl.profile.DevGuiProfile;
import ch.ethz.seb.sebserver.gbl.profile.DevWebServiceProfile; import ch.ethz.seb.sebserver.gbl.profile.DevWebServiceProfile;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile; import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
@ -67,6 +68,8 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements E
private String guiRedirect; private String guiRedirect;
@Value("${sebserver.webservice.api.exam.endpoint.discovery}") @Value("${sebserver.webservice.api.exam.endpoint.discovery}")
private String examAPIDiscoveryEndpoint; private String examAPIDiscoveryEndpoint;
@Value("${sebserver.webservice.api.admin.endpoint}")
private String adminAPIEndpoint;
/** Spring bean name of user password encoder */ /** Spring bean name of user password encoder */
public static final String USER_PASSWORD_ENCODER_BEAN_NAME = "userPasswordEncoder"; public static final String USER_PASSWORD_ENCODER_BEAN_NAME = "userPasswordEncoder";
@ -101,6 +104,7 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter implements E
.ignoring() .ignoring()
.antMatchers("/error") .antMatchers("/error")
.antMatchers(this.examAPIDiscoveryEndpoint) .antMatchers(this.examAPIDiscoveryEndpoint)
.antMatchers(this.adminAPIEndpoint + API.INFO_ENDPOINT + API.LOGO_PATH_SEGMENT + "/**")
.and(); .and();
} }

View file

@ -9,6 +9,7 @@
package ch.ethz.seb.sebserver.gui; package ch.ethz.seb.sebserver.gui;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
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.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@ -30,12 +31,15 @@ public class GuiWebsecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired @Autowired
private InstitutionalAuthenticationEntryPoint institutionalAuthenticationEntryPoint; private InstitutionalAuthenticationEntryPoint institutionalAuthenticationEntryPoint;
@Value("${sebserver.gui.entrypoint:/gui}")
private String guiEntryPoint;
/** 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(
// OAuth entry-points // OAuth entry-points
new AntPathRequestMatcher(API.OAUTH_REVOKE_TOKEN_ENDPOINT), new AntPathRequestMatcher(API.OAUTH_REVOKE_TOKEN_ENDPOINT),
// GUI entry-point // GUI entry-point
new AntPathRequestMatcher("/gui"), // new AntPathRequestMatcher(guiEntryPoint),
// RAP/RWT resources has to be accessible // RAP/RWT resources has to be accessible
new AntPathRequestMatcher("/rwt-resources/**"), new AntPathRequestMatcher("/rwt-resources/**"),
// project specific static resources // project specific static resources
@ -47,7 +51,8 @@ public class GuiWebsecurityConfig extends WebSecurityConfigurerAdapter {
public void configure(final WebSecurity web) { public void configure(final WebSecurity web) {
web web
.ignoring() .ignoring()
.requestMatchers(PUBLIC_URLS); .requestMatchers(PUBLIC_URLS)
.antMatchers(this.guiEntryPoint);
} }
@Override @Override

View file

@ -65,21 +65,25 @@ final class InstitutionalAuthenticationEntryPoint implements AuthenticationEntry
final String logoImageBase64 = requestLogoImage(requestURI); final String logoImageBase64 = requestLogoImage(requestURI);
if (StringUtils.isNotBlank(logoImageBase64)) { if (StringUtils.isNotBlank(logoImageBase64)) {
// forward
request.getSession().setAttribute(API.PARAM_LOGO_IMAGE, logoImageBase64); request.getSession().setAttribute(API.PARAM_LOGO_IMAGE, logoImageBase64);
final RequestDispatcher dispatcher = request.getServletContext()
.getRequestDispatcher(this.guiEntryPoint);
dispatcher.forward(request, response);
// redirect
} else { } else {
request.getSession().removeAttribute(API.PARAM_LOGO_IMAGE); request.getSession().removeAttribute(API.PARAM_LOGO_IMAGE);
response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.setStatus(HttpStatus.UNAUTHORIZED.value());
response.sendRedirect(this.guiEntryPoint);
} }
final RequestDispatcher dispatcher = request.getServletContext()
.getRequestDispatcher(this.guiEntryPoint);
dispatcher.forward(request, response);
} }
private String requestLogoImage(final String requestURI) { private String requestLogoImage(final String requestURI) {
log.debug("Trying to verify insitution from requested entrypoint url: {}", requestURI); log.debug("Trying to verify insitution from requested entrypoint url: {}", requestURI);
final String instPrefix = requestURI.replaceAll("/", "");
if (StringUtils.isBlank(instPrefix)) {
return null;
}
try { try {
final RestTemplate restTemplate = new RestTemplate(); final RestTemplate restTemplate = new RestTemplate();
@ -93,7 +97,7 @@ final class InstitutionalAuthenticationEntryPoint implements AuthenticationEntry
HttpMethod.GET, HttpMethod.GET,
HttpEntity.EMPTY, HttpEntity.EMPTY,
String.class, String.class,
requestURI.replaceAll("/", "")); instPrefix);
if (exchange.getStatusCodeValue() == HttpStatus.OK.value()) { if (exchange.getStatusCodeValue() == HttpStatus.OK.value()) {
return exchange.getBody(); return exchange.getBody();

View file

@ -27,6 +27,7 @@ import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.page.PageContext; import ch.ethz.seb.sebserver.gui.service.page.PageContext;
import ch.ethz.seb.sebserver.gui.service.page.PageService; import ch.ethz.seb.sebserver.gui.service.page.PageService;
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.page.impl.DefaultPageLayout;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils; import ch.ethz.seb.sebserver.gui.service.page.impl.PageUtils;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.ActivateInstitution; import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.ActivateInstitution;
@ -129,7 +130,9 @@ public class InstitutionForm implements TemplateComposer {
.addField(FormBuilder.imageUpload( .addField(FormBuilder.imageUpload(
Domain.INSTITUTION.ATTR_LOGO_IMAGE, Domain.INSTITUTION.ATTR_LOGO_IMAGE,
FORM_LOGO_IMAGE_TEXT_KEY, FORM_LOGO_IMAGE_TEXT_KEY,
institution.logoImage)) institution.logoImage)
.withMaxWidth(DefaultPageLayout.LOGO_IMAGE_MAX_WIDTH)
.withMaxHeight(DefaultPageLayout.LOGO_IMAGE_MAX_HEIGHT))
.buildFor((isNew) .buildFor((isNew)
? this.restService.getRestCall(NewInstitution.class) ? this.restService.getRestCall(NewInstitution.class)
: this.restService.getRestCall(SaveInstitution.class)); : this.restService.getRestCall(SaveInstitution.class));

View file

@ -18,10 +18,23 @@ import ch.ethz.seb.sebserver.gui.widget.ImageUpload;
public final class ImageUploadFieldBuilder extends FieldBuilder<String> { public final class ImageUploadFieldBuilder extends FieldBuilder<String> {
private int maxWidth = 100;
private int maxHeight = 100;
ImageUploadFieldBuilder(final String name, final LocTextKey label, final String value) { ImageUploadFieldBuilder(final String name, final LocTextKey label, final String value) {
super(name, label, value); super(name, label, value);
} }
public ImageUploadFieldBuilder withMaxWidth(final int width) {
this.maxWidth = width;
return this;
}
public ImageUploadFieldBuilder withMaxHeight(final int height) {
this.maxHeight = height;
return this;
}
@Override @Override
void build(final FormBuilder builder) { void build(final FormBuilder builder) {
@ -35,7 +48,9 @@ public final class ImageUploadFieldBuilder extends FieldBuilder<String> {
final ImageUpload imageUpload = builder.widgetFactory.imageUploadLocalized( final ImageUpload imageUpload = builder.widgetFactory.imageUploadLocalized(
fieldGrid, fieldGrid,
new LocTextKey("sebserver.overall.upload"), new LocTextKey("sebserver.overall.upload"),
builder.readonly || this.readonly); builder.readonly || this.readonly,
this.maxWidth,
this.maxHeight);
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false); final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
imageUpload.setLayoutData(gridData); imageUpload.setLayoutData(gridData);
imageUpload.setImageBase64(this.value); imageUpload.setImageBase64(this.value);

View file

@ -17,11 +17,14 @@ 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;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.MessageBox;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -49,6 +52,9 @@ public class DefaultPageLayout implements TemplateComposer {
private static final Logger log = LoggerFactory.getLogger(DefaultPageLayout.class); private static final Logger log = LoggerFactory.getLogger(DefaultPageLayout.class);
public static final int LOGO_IMAGE_MAX_WIDTH = 400;
public static final int LOGO_IMAGE_MAX_HEIGHT = 80;
private final WidgetFactory widgetFactory; private final WidgetFactory widgetFactory;
private final PolyglotPageService polyglotPageService; private final PolyglotPageService polyglotPageService;
private final AuthorizationContextHolder authorizationContextHolder; private final AuthorizationContextHolder authorizationContextHolder;
@ -155,9 +161,9 @@ public class DefaultPageLayout implements TemplateComposer {
final Composite logo = new Composite(logoBar, SWT.NONE); final Composite logo = new Composite(logoBar, SWT.NONE);
final GridData logoCell = new GridData(SWT.LEFT, SWT.CENTER, true, true); final GridData logoCell = new GridData(SWT.LEFT, SWT.CENTER, true, true);
logoCell.minimumHeight = 80; logoCell.minimumHeight = LOGO_IMAGE_MAX_HEIGHT;
logoCell.heightHint = 80; logoCell.heightHint = LOGO_IMAGE_MAX_HEIGHT;
logoCell.minimumWidth = 400; logoCell.minimumWidth = LOGO_IMAGE_MAX_WIDTH;
logoCell.horizontalIndent = 50; logoCell.horizontalIndent = 50;
logo.setLayoutData(logoCell); logo.setLayoutData(logoCell);
@ -283,8 +289,19 @@ public class DefaultPageLayout implements TemplateComposer {
new ByteArrayInputStream(imageBase64.getBytes(StandardCharsets.UTF_8)), new ByteArrayInputStream(imageBase64.getBytes(StandardCharsets.UTF_8)),
false); false);
final Display display = pageContext.getShell().getDisplay();
final Image image = new Image(display, input);
final Rectangle imageBounds = image.getBounds();
final int width = (imageBounds.width > LOGO_IMAGE_MAX_WIDTH)
? LOGO_IMAGE_MAX_WIDTH
: imageBounds.width;
final int height = (imageBounds.height > LOGO_IMAGE_MAX_HEIGHT)
? LOGO_IMAGE_MAX_HEIGHT
: imageBounds.height;
final ImageData imageData = image.getImageData().scaledTo(width, height);
logo.setData(RWT.CUSTOM_VARIANT, "bgLogoNoImage"); logo.setData(RWT.CUSTOM_VARIANT, "bgLogoNoImage");
logo.setBackgroundImage(new Image(pageContext.getShell().getDisplay(), input)); logo.setBackgroundImage(new Image(display, imageData));
} catch (final Exception e) { } catch (final Exception e) {
log.warn("Get institutional logo failed: {}", e.getMessage()); log.warn("Get institutional logo failed: {}", e.getMessage());

View file

@ -32,6 +32,7 @@ import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Composite;
@ -54,6 +55,9 @@ public final class ImageUpload extends Composite {
private final Composite imageCanvas; private final Composite imageCanvas;
private final FileUpload fileUpload; private final FileUpload fileUpload;
private final int maxWidth;
private final int maxHeight;
private Consumer<String> errorHandler; private Consumer<String> errorHandler;
private String imageBase64 = null; private String imageBase64 = null;
private boolean loadNewImage = false; private boolean loadNewImage = false;
@ -63,12 +67,16 @@ public final class ImageUpload extends Composite {
final Composite parent, final Composite parent,
final ServerPushService serverPushService, final ServerPushService serverPushService,
final I18nSupport i18nSupport, final I18nSupport i18nSupport,
final boolean readonly) { final boolean readonly,
final int maxWidth,
final int maxHeight) {
super(parent, SWT.NONE); super(parent, SWT.NONE);
super.setLayout(new GridLayout(1, false)); super.setLayout(new GridLayout(1, false));
this.serverPushService = serverPushService; this.serverPushService = serverPushService;
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
if (!readonly) { if (!readonly) {
this.fileUpload = new FileUpload(this, SWT.NONE); this.fileUpload = new FileUpload(this, SWT.NONE);
@ -189,8 +197,14 @@ public final class ImageUpload extends Composite {
imageUpload.imageCanvas.setData(RWT.CUSTOM_VARIANT, "bgLogoNoImage"); imageUpload.imageCanvas.setData(RWT.CUSTOM_VARIANT, "bgLogoNoImage");
final Image image = new Image(imageUpload.imageCanvas.getDisplay(), input); final Image image = new Image(imageUpload.imageCanvas.getDisplay(), input);
final ImageData imageData = image.getImageData().scaledTo(200, 100); final Rectangle imageBounds = image.getBounds();
final int width = (imageBounds.width > imageUpload.maxWidth)
? imageUpload.maxWidth
: imageBounds.width;
final int height = (imageBounds.height > imageUpload.maxHeight)
? imageUpload.maxHeight
: imageBounds.height;
final ImageData imageData = image.getImageData().scaledTo(width, height);
imageUpload.imageCanvas.setBackgroundImage(new Image(imageUpload.imageCanvas.getDisplay(), imageData)); imageUpload.imageCanvas.setBackgroundImage(new Image(imageUpload.imageCanvas.getDisplay(), imageData));
} }

View file

@ -48,6 +48,7 @@ import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey; import ch.ethz.seb.sebserver.gui.service.i18n.LocTextKey;
import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService; import ch.ethz.seb.sebserver.gui.service.i18n.PolyglotPageService;
import ch.ethz.seb.sebserver.gui.service.page.PageService; import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.impl.DefaultPageLayout;
import ch.ethz.seb.sebserver.gui.service.push.ServerPushService; import ch.ethz.seb.sebserver.gui.service.push.ServerPushService;
@Lazy @Lazy
@ -584,16 +585,33 @@ public class WidgetFactory {
return thresholdList; return thresholdList;
} }
public ImageUpload imageUploadLocalized( public ImageUpload logoImageUploadLocalized(
final Composite parent, final Composite parent,
final LocTextKey locTextKey, final LocTextKey locTextKey,
final boolean readonly) { final boolean readonly) {
return imageUploadLocalized(
parent,
locTextKey,
readonly,
DefaultPageLayout.LOGO_IMAGE_MAX_WIDTH,
DefaultPageLayout.LOGO_IMAGE_MAX_HEIGHT);
}
public ImageUpload imageUploadLocalized(
final Composite parent,
final LocTextKey locTextKey,
final boolean readonly,
final int maxWidth,
final int maxHeight) {
final ImageUpload imageUpload = new ImageUpload( final ImageUpload imageUpload = new ImageUpload(
parent, parent,
this.serverPushService, this.serverPushService,
this.i18nSupport, this.i18nSupport,
readonly); readonly,
maxWidth,
maxHeight);
this.polyglotPageService.injectI18n(imageUpload, locTextKey); this.polyglotPageService.injectI18n(imageUpload, locTextKey);
return imageUpload; return imageUpload;