Merge branch 'patch-1.0.2' into development

This commit is contained in:
anhefti 2020-07-06 16:30:26 +02:00
commit d7f79fb3cc
8 changed files with 109 additions and 17 deletions

View file

@ -41,8 +41,11 @@ public final class API {
public static final String OAUTH_TOKEN_ENDPOINT = OAUTH_ENDPOINT + "/token";
public static final String OAUTH_REVOKE_TOKEN_ENDPOINT = OAUTH_ENDPOINT + "/revoke-token";
public static final String CURRENT_USER_ENDPOINT = API.USER_ACCOUNT_ENDPOINT + "/me";
public static final String CURRENT_USER_PATH_SEGMENT = "/me";
public static final String CURRENT_USER_ENDPOINT = API.USER_ACCOUNT_ENDPOINT + CURRENT_USER_PATH_SEGMENT;
public static final String SELF_PATH_SEGMENT = "/self";
public static final String LOGIN_PATH_SEGMENT = "/loglogin";
public static final String LOGOUT_PATH_SEGMENT = "/loglogout";
public static final String INFO_ENDPOINT = "/info";
public static final String INFO_PARAM_INST_SUFFIX = "urlSuffix";

View file

@ -18,5 +18,7 @@ public enum UserLogActivityType {
PASSWORD_CHANGE,
DEACTIVATE,
ACTIVATE,
DELETE
DELETE,
LOGIN,
LOGOUT
}

View file

@ -8,12 +8,15 @@
package ch.ethz.seb.sebserver.gui.service.remote.webservice.auth;
import ch.ethz.seb.sebserver.ClientHttpRequestFactoryService;
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.util.Result;
import ch.ethz.seb.sebserver.gbl.util.Utils;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -41,13 +44,12 @@ import org.springframework.web.client.ResponseExtractor;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import ch.ethz.seb.sebserver.ClientHttpRequestFactoryService;
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.util.Result;
import ch.ethz.seb.sebserver.gbl.util.Utils;
@Lazy
@Component
@ -148,6 +150,8 @@ public class OAuth2AuthorizationContextHolder implements AuthorizationContextHol
private final DisposableOAuth2RestTemplate restTemplate;
private final String revokeTokenURI;
private final String currentUserURI;
private final String loginLogURI;
private final String logoutLogURI;
private Result<UserInfo> loggedInUser = null;
@ -173,6 +177,8 @@ public class OAuth2AuthorizationContextHolder implements AuthorizationContextHol
this.revokeTokenURI = webserviceURIService.getOAuthRevokeTokenURI();
this.currentUserURI = webserviceURIService.getCurrentUserRequestURI();
this.loginLogURI = webserviceURIService.getLoginLogPostURI();
this.logoutLogURI = webserviceURIService.getLogoutLogPostURI();
}
@Override
@ -216,6 +222,19 @@ public class OAuth2AuthorizationContextHolder implements AuthorizationContextHol
this.restTemplate.getAccessToken();
log.debug("Got token for user: {}", username);
this.loggedInUser = getLoggedInUser();
// call log login on webservice API
try {
final ResponseEntity<Void> response = this.restTemplate.postForEntity(
this.loginLogURI,
null,
Void.class);
if (response.getStatusCode() != HttpStatus.OK) {
log.error("Failed to log login: {}", response.getStatusCode());
}
} catch (final Exception e) {
log.error("Failed to log login: {}", e.getMessage());
}
return true;
} catch (final OAuth2AccessDeniedException | AccessDeniedException e) {
log.info("Access Denied for user: {}", username);
@ -225,6 +244,19 @@ public class OAuth2AuthorizationContextHolder implements AuthorizationContextHol
@Override
public boolean logout() {
// call log logout on webservice API
try {
final ResponseEntity<Void> response = this.restTemplate.postForEntity(
this.logoutLogURI,
null,
Void.class);
if (response.getStatusCode() != HttpStatus.OK) {
log.error("Failed to log logout: {}", response.getStatusCode());
}
} catch (final Exception e) {
log.error("Failed to log logout: {}", e.getMessage());
}
// set this context invalid to force creation of a new context on next request
this.valid = false;
this.loggedInUser = null;

View file

@ -31,7 +31,8 @@ public class WebserviceURIService {
@Value("${sebserver.gui.webservice.apipath}") final String webserviceAPIPath) {
this.servletContextPath = servletContextPath;
this.webserviceServerAddress = webserviceProtocol + "://" + webserviceServerAddress + ":" + webserviceServerPort;
this.webserviceServerAddress =
webserviceProtocol + "://" + webserviceServerAddress + ":" + webserviceServerPort;
this.webserviceURIBuilder = UriComponentsBuilder
.fromHttpUrl(webserviceProtocol + "://" + webserviceServerAddress)
.port(webserviceServerPort)
@ -66,4 +67,16 @@ public class WebserviceURIService {
.path(API.CURRENT_USER_ENDPOINT)
.toUriString();
}
public String getLoginLogPostURI() {
return getURIBuilder()
.path(API.USER_ACCOUNT_ENDPOINT + API.LOGIN_PATH_SEGMENT)
.toUriString();
}
public String getLogoutLogPostURI() {
return getURIBuilder()
.path(API.USER_ACCOUNT_ENDPOINT + API.LOGOUT_PATH_SEGMENT)
.toUriString();
}
}

View file

@ -15,6 +15,7 @@ import ch.ethz.seb.sebserver.gbl.api.EntityType;
import ch.ethz.seb.sebserver.gbl.model.Entity;
import ch.ethz.seb.sebserver.gbl.model.user.UserAccount;
import ch.ethz.seb.sebserver.gbl.model.user.UserActivityLog;
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
import ch.ethz.seb.sebserver.gbl.model.user.UserLogActivityType;
import ch.ethz.seb.sebserver.gbl.util.Result;
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.impl.SEBServerUser;
@ -24,6 +25,18 @@ public interface UserActivityLogDAO extends
EntityDAO<UserActivityLog, UserActivityLog>,
UserRelatedEntityDAO<UserActivityLog> {
/** Create a user activity log entry for the current users login action
*
* @param user the UserInfo
* @return Result of the Entity or referring to an Error if happened */
Result<UserInfo> logLogin(UserInfo user);
/** Create a user activity log entry for the current user logut action
*
* @param user the UserInfo
* @return Result of the Entity or referring to an Error if happened */
Result<UserInfo> logLogout(UserInfo user);
/** Create a user activity log entry for the current user of activity type CREATE
*
* @param entity the Entity

View file

@ -38,6 +38,7 @@ import ch.ethz.seb.sebserver.gbl.model.Entity;
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
import ch.ethz.seb.sebserver.gbl.model.user.UserAccount;
import ch.ethz.seb.sebserver.gbl.model.user.UserActivityLog;
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
import ch.ethz.seb.sebserver.gbl.model.user.UserLogActivityType;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
import ch.ethz.seb.sebserver.gbl.util.Result;
@ -82,6 +83,16 @@ public class UserActivityLogDAOImpl implements UserActivityLogDAO {
return EntityType.USER_ACTIVITY_LOG;
}
@Override
public Result<UserInfo> logLogin(final UserInfo user) {
return log(UserLogActivityType.LOGIN, user);
}
@Override
public Result<UserInfo> logLogout(final UserInfo user) {
return log(UserLogActivityType.LOGOUT, user);
}
@Override
@Transactional
public <E extends Entity> Result<E> logCreate(final E entity) {

View file

@ -83,7 +83,7 @@ public class UserAccountController extends ActivatableEntityController<UserInfo,
this.userPasswordEncoder = userPasswordEncoder;
}
@RequestMapping(path = "/me", method = RequestMethod.GET)
@RequestMapping(path = API.CURRENT_USER_PATH_SEGMENT, method = RequestMethod.GET)
public UserInfo loggedInUser() {
return this.authorization
.getUserService()
@ -91,6 +91,22 @@ public class UserAccountController extends ActivatableEntityController<UserInfo,
.getUserInfo();
}
@RequestMapping(path = API.LOGIN_PATH_SEGMENT, method = RequestMethod.POST)
public void logLogin() {
this.userActivityLogDAO.logLogin(this.authorization
.getUserService()
.getCurrentUser()
.getUserInfo());
}
@RequestMapping(path = API.LOGOUT_PATH_SEGMENT, method = RequestMethod.POST)
public void logLogout() {
this.userActivityLogDAO.logLogout(this.authorization
.getUserService()
.getCurrentUser()
.getUserInfo());
}
@Override
protected SqlTable getSQLTableOfEntity() {
return UserRecordDynamicSqlSupport.userRecord;

View file

@ -46,6 +46,8 @@ sebserver.overall.types.activityType.PASSWORD_CHANGE=Password Change
sebserver.overall.types.activityType.DEACTIVATE=Deactivate
sebserver.overall.types.activityType.ACTIVATE=Activate
sebserver.overall.types.activityType.DELETE=Delete
sebserver.overall.types.activityType.LOGIN=Login
sebserver.overall.types.activityType.LOGOUT=Logout
sebserver.overall.types.entityType.CONFIGURATION_ATTRIBUTE=Configuration Attribute
sebserver.overall.types.entityType.CONFIGURATION_VALUE=Configuration Value