fixes for test release 0.2.1

This commit is contained in:
anhefti 2019-04-09 09:44:52 +02:00
parent cee8e27fe2
commit a857e313d5
16 changed files with 136 additions and 89 deletions

View file

@ -89,7 +89,9 @@ public class InstitutionList implements TemplateComposer {
.withColumn(new ColumnDefinition<>(
Domain.INSTITUTION.ATTR_ACTIVE,
ACTIVE_TEXT_KEY,
entity -> entity.active,
entity -> this.pageService
.getResourceService()
.localizedActivityResource().apply(entity.active),
true))
.withDefaultAction(pageActionBuilder
.newAction(ActionDefinition.INSTITUTION_VIEW_FROM_LIST)

View file

@ -186,7 +186,7 @@ public class LmsSetupForm implements TemplateComposer {
.withEntityKey(entityKey)
.publishIf(() -> modifyGrant && readonly && institutionActive)
.newAction(ActionDefinition.LMS_SETUP_TEST)
.newAction(ActionDefinition.LMS_SETUP_SAVE_AND_TEST)
.withEntityKey(entityKey)
.withExec(action -> this.testLmsSetup(action, formHandle))
.ignoreMoveAwayFromEdit()

View file

@ -25,6 +25,7 @@ import org.springframework.stereotype.Component;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gui.service.i18n.I18nSupport;
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.TemplateComposer;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.SEBServerAuthorizationContext;
@ -38,18 +39,16 @@ public class LoginPage implements TemplateComposer {
private static final Logger log = LoggerFactory.getLogger(LoginPage.class);
private final PageService pageService;
private final AuthorizationContextHolder authorizationContextHolder;
private final WidgetFactory widgetFactory;
private final I18nSupport i18nSupport;
public LoginPage(
final AuthorizationContextHolder authorizationContextHolder,
final WidgetFactory widgetFactory,
final I18nSupport i18nSupport) {
this.authorizationContextHolder = authorizationContextHolder;
this.widgetFactory = widgetFactory;
this.i18nSupport = i18nSupport;
public LoginPage(final PageService pageService) {
this.pageService = pageService;
this.authorizationContextHolder = pageService.getAuthorizationContextHolder();
this.widgetFactory = pageService.getWidgetFactory();
this.i18nSupport = pageService.getI18nSupport();
}
@Override
@ -125,7 +124,7 @@ public class LoginPage implements TemplateComposer {
final PageContext pageContext,
final String message) {
pageContext.logout();
this.pageService.logout(pageContext);
final MessageBox error = new Message(
pageContext.getShell(),
this.i18nSupport.getText("sebserver.login.failed.title"),

View file

@ -112,7 +112,7 @@ public class UserAccountChangePasswordForm implements TemplateComposer {
// NOTE: in this case the user changed the password of the own account
// this should cause an logout with specified message that password change
// was successful and the pointing the need of re login with the new password
pageContext.logout();
this.pageService.logout(pageContext);
final MessageBox error = new Message(
pageContext.getShell(),
this.i18nSupport.getText("sebserver.login.password.change"),

View file

@ -145,10 +145,10 @@ public enum ActionDefinition {
ImageIcon.EDIT,
PageStateDefinition.LMS_SETUP_EDIT,
ActionCategory.FORM),
LMS_SETUP_TEST(
new LocTextKey("sebserver.lmssetup.action.test"),
LMS_SETUP_SAVE_AND_TEST(
new LocTextKey("sebserver.lmssetup.action.savetest"),
ImageIcon.TEST,
PageStateDefinition.LMS_SETUP_EDIT,
PageStateDefinition.LMS_SETUP_VIEW,
ActionCategory.FORM),
LMS_SETUP_TEST_AND_SAVE(
new LocTextKey("sebserver.lmssetup.action.testsave"),

View file

@ -61,7 +61,7 @@ public class ActivitiesPane implements TemplateComposer {
@Override
public void compose(final PageContext pageContext) {
final UserInfo userInfo = this.currentUser
.getOrHandleError(pageContext::logoutOnError);
.getOrHandleError(t -> this.pageService.logoutOnError(t, pageContext));
final Label activities = this.widgetFactory.labelLocalized(
pageContext.getParent(),

View file

@ -32,6 +32,7 @@ import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gbl.util.Tuple;
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.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.institution.GetInstitutionNames;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.lmssetup.GetLmsSetupNames;
@ -41,8 +42,13 @@ import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.CurrentUser;
@Lazy
@Service
@GuiProfile
/** Defines functionality to get resources or functions of resources to feed e.g. selection or
* combo-box content. */
public class ResourceService {
public static final LocTextKey ACTIVE_TEXT_KEY = new LocTextKey("sebserver.overall.status.active");
public static final LocTextKey INACTIVE_TEXT_KEY = new LocTextKey("sebserver.overall.status.inactive");
private final I18nSupport i18nSupport;
private final RestService restService;
private final CurrentUser currentUser;
@ -221,4 +227,10 @@ public class ResourceService {
.collect(Collectors.toList());
}
public Function<Boolean, String> localizedActivityResource() {
return activity -> activity
? this.i18nSupport.getText(ACTIVE_TEXT_KEY)
: this.i18nSupport.getText(INACTIVE_TEXT_KEY);
}
}

View file

@ -90,6 +90,11 @@ public interface PageContext {
* @return this PageContext instance (builder pattern) */
PageContext withAttribute(String key, String value);
/** Gets a copy of this PageContext with cleared attribute map.
*
* @return a copy of this PageContext with cleared attribute map. */
PageContext clearAttributes();
/** Get the attribute value that is mapped to the given name or null of no mapping exists
*
* @param name the attribute name
@ -167,10 +172,6 @@ public interface PageContext {
/** Forward to login page */
void forwardToLoginPage();
/** This triggers a logout on the current authorization context to logout the current user
* and forward to the login page with showing a successful logout message to the user. */
void logout();
/** Notify an error dialog to the user with specified error message and
* optional exception instance
*
@ -185,12 +186,6 @@ public interface PageContext {
* @return adaption to be used with functional approaches */
<T> T notifyError(Throwable error);
default <T> T logoutOnError(final Throwable t) {
log.error("Unexpected, Current User related error.Automatically logout and cleanup current user session. ", t);
logout();
return null;
}
/** Publish and shows a message to the user with the given localized title and
* localized message. The message text can also be HTML text as far as RWT supports it.
*

View file

@ -14,6 +14,9 @@ import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.ethz.seb.sebserver.gbl.api.API;
import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
@ -23,6 +26,7 @@ import ch.ethz.seb.sebserver.gbl.model.Page;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.gui.content.action.ActionDefinition;
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
import ch.ethz.seb.sebserver.gui.service.ResourceService;
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.PolyglotPageService;
@ -32,6 +36,7 @@ import ch.ethz.seb.sebserver.gui.service.page.event.PageEvent;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
import ch.ethz.seb.sebserver.gui.table.TableBuilder;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
@ -39,21 +44,33 @@ import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
* with forms and tables as well as dealing with page actions */
public interface PageService {
/** get the WidgetFactory service
Logger log = LoggerFactory.getLogger(PageService.class);
/** Get the WidgetFactory service
*
* @return the WidgetFactory service */
WidgetFactory getWidgetFactory();
/** get the polyglotPageService service
/** Get the polyglotPageService service
*
* @return the polyglotPageService service */
PolyglotPageService getPolyglotPageService();
/** get the I18nSupport (internationalization support) service
/** Get the underling AuthorizationContextHolder for the current user session
*
* @return the underling AuthorizationContextHolder for the current user session */
AuthorizationContextHolder getAuthorizationContextHolder();
/** Get the I18nSupport (internationalization support) service
*
* @return the I18nSupport (internationalization support) service */
I18nSupport getI18nSupport();
/** Get the ResourceService
*
* @return the ResourceService */
ResourceService getResourceService();
/** get the JSONMapper for parse, read and write JSON
*
* @return the JSONMapper for parse, read and write JSON */
@ -117,6 +134,16 @@ public interface PageService {
return new PageActionBuilder(this, pageContext);
}
/** This triggers a logout on the current authorization context to logout the current user
* and forward to the login page with showing a successful logout message to the user. */
void logout(PageContext pageContext);
default <T> T logoutOnError(final Throwable t, final PageContext pageContext) {
log.error("Unexpected, Current User related error.Automatically logout and cleanup current user session. ", t);
logout(pageContext);
return null;
}
/** Clears the PageState of the current users page */
void clearState();

View file

@ -35,8 +35,8 @@ 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.PolyglotPageService;
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.PageContext.AttributeKeys;
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.remote.webservice.auth.AuthorizationContextHolder;
import ch.ethz.seb.sebserver.gui.widget.Message;
@ -52,21 +52,18 @@ public class DefaultPageLayout implements TemplateComposer {
private final WidgetFactory widgetFactory;
private final PolyglotPageService polyglotPageService;
private final AuthorizationContextHolder authorizationContextHolder;
private final PageService pageStateService;
private final PageService pageService;
private final String sebServerVersion;
private final boolean multilingual;
public DefaultPageLayout(
final WidgetFactory widgetFactory,
final PolyglotPageService polyglotPageService,
final AuthorizationContextHolder authorizationContextHolder,
final PageService pageStateService,
final PageService pageService,
final Environment environment) {
this.widgetFactory = widgetFactory;
this.polyglotPageService = polyglotPageService;
this.authorizationContextHolder = authorizationContextHolder;
this.pageStateService = pageStateService;
this.widgetFactory = pageService.getWidgetFactory();
this.polyglotPageService = pageService.getPolyglotPageService();
this.authorizationContextHolder = pageService.getAuthorizationContextHolder();
this.pageService = pageService;
this.sebServerVersion = environment.getProperty("sebserver.version", Constants.EMPTY_NOTE);
this.multilingual = BooleanUtils.toBoolean(environment.getProperty("sebserver.gui.multilingual", "false"));
}
@ -126,25 +123,13 @@ public class DefaultPageLayout implements TemplateComposer {
username.setText(this.authorizationContextHolder
.getAuthorizationContext()
.getLoggedInUser()
.get(pageContext::logoutOnError).username);
.get(t -> this.pageService.logoutOnError(t, pageContext)).username);
final Button logout = this.widgetFactory.buttonLocalized(headerRight, "sebserver.logout");
logout.setLayoutData(new GridData(SWT.RIGHT, SWT.FILL, true, true));
logout.setData(RWT.CUSTOM_VARIANT, "header");
logout.addListener(SWT.Selection, event -> {
final boolean logoutSuccessful = this.authorizationContextHolder
.getAuthorizationContext()
.logout();
if (!logoutSuccessful) {
// TODO error handling
}
this.pageStateService.clearState();
// forward to login page with success message
pageContext.forwardToLoginPage();
this.pageService.logout(pageContext);
// show successful logout message
final MessageBox logoutSuccess = new Message(
pageContext.getShell(),

View file

@ -209,6 +209,16 @@ public class PageContextImpl implements PageContext {
attrs);
}
@Override
public PageContext clearAttributes() {
return new PageContextImpl(
this.i18nSupport,
this.composerService,
this.root,
this.parent,
null);
}
@Override
public void applyConfirmDialog(final LocTextKey confirmMessage, final Consumer<Boolean> callback) {
final Message messageBox = new Message(
@ -235,7 +245,8 @@ public class PageContextImpl implements PageContext {
@Override
public void forwardToLoginPage() {
forwardToPage(this.composerService.loginPage());
this.clearAttributes()
.forwardToPage(this.composerService.loginPage());
}
@Override
@ -288,20 +299,6 @@ public class PageContextImpl implements PageContext {
return null;
}
@Override
public void logout() {
// just to be sure we leave a clean and proper authorizationContext
try {
((ComposerServiceImpl) this.composerService).authorizationContextHolder
.getAuthorizationContext()
.logout();
} catch (final Exception e) {
log.info("Cleanup logout failed: {}", e.getMessage());
}
forwardToLoginPage();
}
@Override
public String toString() {
return "PageContextImpl [root=" + this.root + ", parent=" + this.parent + ", attributes=" + this.attributes

View file

@ -28,6 +28,7 @@ import ch.ethz.seb.sebserver.gbl.model.Page;
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
import ch.ethz.seb.sebserver.gui.service.ResourceService;
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.PolyglotPageService;
@ -41,6 +42,7 @@ import ch.ethz.seb.sebserver.gui.service.page.event.ActionPublishEvent;
import ch.ethz.seb.sebserver.gui.service.page.event.PageEvent;
import ch.ethz.seb.sebserver.gui.service.page.event.PageEventListener;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.auth.AuthorizationContextHolder;
import ch.ethz.seb.sebserver.gui.table.TableBuilder;
import ch.ethz.seb.sebserver.gui.widget.WidgetFactory;
@ -60,15 +62,21 @@ public class PageServiceImpl implements PageService {
private final JSONMapper jsonMapper;
private final WidgetFactory widgetFactory;
private final PolyglotPageService polyglotPageService;
private final ResourceService resourceService;
private final AuthorizationContextHolder authorizationContextHolder;
public PageServiceImpl(
final JSONMapper jsonMapper,
final WidgetFactory widgetFactory,
final PolyglotPageService polyglotPageService) {
final PolyglotPageService polyglotPageService,
final ResourceService resourceService,
final AuthorizationContextHolder authorizationContextHolder) {
this.jsonMapper = jsonMapper;
this.widgetFactory = widgetFactory;
this.polyglotPageService = polyglotPageService;
this.resourceService = resourceService;
this.authorizationContextHolder = authorizationContextHolder;
}
@Override
@ -81,11 +89,21 @@ public class PageServiceImpl implements PageService {
return this.polyglotPageService;
}
@Override
public AuthorizationContextHolder getAuthorizationContextHolder() {
return this.authorizationContextHolder;
}
@Override
public I18nSupport getI18nSupport() {
return this.widgetFactory.getI18nSupport();
}
@Override
public ResourceService getResourceService() {
return this.resourceService;
}
@Override
public JSONMapper getJSONMapper() {
return this.jsonMapper;
@ -199,6 +217,27 @@ public class PageServiceImpl implements PageService {
return new TableBuilder<>(this, apiCall);
}
@Override
public void logout(final PageContext pageContext) {
this.clearState();
try {
final boolean logoutSuccessful = this.authorizationContextHolder
.getAuthorizationContext()
.logout();
if (!logoutSuccessful) {
// TODO error handling
}
} catch (final Exception e) {
log.info("Cleanup logout failed: {}", e.getMessage());
} finally {
pageContext.forwardToLoginPage();
}
}
@Override
public void clearState() {
try {

View file

@ -24,21 +24,6 @@ import ch.ethz.seb.sebserver.gui.service.page.PageService;
import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
/** <code>
* new TableBuilder<T>(RestCall)
* .withPaging(pageSize)
* .withFilterAttribute(attribute.TableFilterAttribute)
* .withColumn(new ColumnDefinition(
* columnName:String,
* displayName:LocTextKey,
* tooltip:LocTextKey,
* width:int,
* valueSupplier:Function<ROW, String>,
* sortable:boolean
* .withAction(action:TableRowAction)
* .withSelectableRows(boolean)
* .compose(parent:Composit, group:Composite);
* </code> */
public class TableBuilder<ROW extends Entity> {
private final PageService pageService;

View file

@ -5,7 +5,7 @@ spring.mandatory-file-encoding=UTF-8
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
sebserver.version=0.2 pre-beta
sebserver.version=0.2.1 pre-beta
sebserver.supported.languages=en,de
# comma separated list of known possible OpenEdX API access token request endpoints

View file

@ -18,6 +18,9 @@ sebserver.overall.action.close=Close
sebserver.overall.action.goAwayFromEditPageConfirm=Are you sure to leave this page? Any unsaved data will be lost.
sebserver.overall.action.category.varia=Varia
sebserver.overall.status.active=Active
sebserver.overall.status.inactive=Inactive
################################
# Form validation and messages
################################
@ -73,7 +76,7 @@ sebserver.institution.list.empty=No Institution has been found. Please adapt the
sebserver.institution.list.title=Institutions
sebserver.institution.list.column.name=Name
sebserver.institution.list.column.urlSuffix=URL Suffix
sebserver.institution.list.column.active=Active
sebserver.institution.list.column.active=Status
sebserver.institution.action.list=Institution
sebserver.institution.action.form=Institution
@ -169,7 +172,7 @@ sebserver.lmssetup.action.new=New LMS Setup
sebserver.lmssetup.action.list.view=View LMS Setup
sebserver.lmssetup.action.list.modify=Edit LMS Setup
sebserver.lmssetup.action.modify=Edit
sebserver.lmssetup.action.test=Test
sebserver.lmssetup.action.savetest=Test And Save
sebserver.lmssetup.action.testsave=Test And Save
sebserver.lmssetup.action.test.ok=Successfully connected to the course API
sebserver.lmssetup.action.test.tokenRequestError=The API access was denied: {0}

View file

@ -18,6 +18,9 @@ sebserver.overall.action.close=Close
sebserver.overall.action.goAwayFromEditPageConfirm=Are you sure you want to leave this page? Unsaved data will be lost.
sebserver.overall.action.category.varia=Varia
sebserver.overall.status.active=Active
sebserver.overall.status.inactive=Inactive
################################
# Form validation and messages
################################
@ -73,7 +76,7 @@ sebserver.institution.list.empty=No institution has been found. Please adapt the
sebserver.institution.list.title=Institutions
sebserver.institution.list.column.name=Name
sebserver.institution.list.column.urlSuffix=URL Suffix
sebserver.institution.list.column.active=Active
sebserver.institution.list.column.active=Status
sebserver.institution.action.list=Institution
sebserver.institution.action.form=Institution
@ -169,7 +172,7 @@ sebserver.lmssetup.action.new=Add LMS Setup
sebserver.lmssetup.action.list.view=View LMS Setup
sebserver.lmssetup.action.list.modify=Edit LMS Setup
sebserver.lmssetup.action.modify=Edit
sebserver.lmssetup.action.test=Test
sebserver.lmssetup.action.savetest=Test And Save
sebserver.lmssetup.action.testsave=Test And Save
sebserver.lmssetup.action.test.ok=Successfully connected to the course API
sebserver.lmssetup.action.test.tokenRequestError=The API access was denied: {0}