Skip to content

Commit

Permalink
Added injectable class to provide the requesting user of a REST call
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonDan committed May 17, 2020
1 parent 16bc971 commit 344674e
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class SecureRequestBoundary<BOUNDARY extends Annotation, USER extends OJU
private final IBoundaryValidation<BOUNDARY, USER> boundaryValidation;
private final Class<USER> userType;
private IBeanContainer<USER> users;
private UserRequestContext userRequestContext;
private TransactionalExecution transactionalExecution;

public SecureRequestBoundary(IBoundaryValidation<BOUNDARY, USER> pBoundaryValidation, Class<USER> pUserType)
Expand All @@ -56,10 +57,7 @@ public void filter(ContainerRequestContext pRequestContext)
if (!boundaryMethod.isAnnotationPresent(boundaryValidation.getBoundaryType()))
return;

if (users == null) //Initialize lazy to assure that CDI is ready
users = ICdiControl.current().createInjected(new ParameterizedTypeImpl(IBeanContainer.class, userType));
if (transactionalExecution == null)
transactionalExecution = ICdiControl.current().createInjected(TransactionalExecution.class);
_initializeCdiComponents();

final String token = _retrieveTokenFromHeader(pRequestContext);
final DecodedJWT decoded = JWTUtil.decodeJwt(token);
Expand All @@ -75,13 +73,28 @@ public void filter(ContainerRequestContext pRequestContext)
final BOUNDARY boundaryAnnotation = boundaryMethod.getAnnotation(boundaryValidation.getBoundaryType());
if (!(boundaryValidation).isUserAllowedToCrossBoundary(boundaryAnnotation, authenticatedUser.get()))
pRequestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());

userRequestContext.setAuthenticatedUserForRequest(authenticatedUser.get());
}
catch (JWTVerificationException pE)
{
pRequestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
}
}

/**
* Lazily initializes CDI components. Cannot be done while construction because CDI container is not booted then.
*/
private void _initializeCdiComponents()
{
if (users == null)
users = ICdiControl.current().createInjected(new ParameterizedTypeImpl(IBeanContainer.class, userType));
if (userRequestContext == null)
userRequestContext = ICdiControl.current().createInjected(UserRequestContext.class);
if (transactionalExecution == null)
transactionalExecution = ICdiControl.current().createInjected(TransactionalExecution.class);
}

/**
* Retrieves the string based JWT from the HTTP header.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package de.adito.ojcms.rest.security;

import de.adito.ojcms.rest.security.user.OJUser;

import javax.enterprise.context.RequestScoped;
import java.util.Objects;

/**
* Provides the user context of a REST request.
*
* @author Simon Danner, 11.05.2020
*/
@RequestScoped
public class UserRequestContext
{
private OJUser requestingUser;

/**
* The requesting user of the currently active REST call.
*
* @param <USER> the generic type of the user of the application
* @return the requesting user
* @throws IllegalStateException if no user has been set for the call
*/
public <USER extends OJUser> USER getRequestingUser()
{
if (requestingUser == null)
throw new IllegalStateException("No user set for active request!");

//noinspection unchecked
return (USER) requestingUser;
}

/**
* Sets the requesting user for the currently active REST call.
*
* @param pRequestingUser the requesting user to set for the call
*/
void setAuthenticatedUserForRequest(OJUser pRequestingUser)
{
requestingUser = Objects.requireNonNull(pRequestingUser);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package de.adito.ojcms.rest.testapplication;

import de.adito.ojcms.beans.IBeanContainer;
import de.adito.ojcms.rest.security.UserRequestContext;
import de.adito.ojcms.rest.security.user.OJUser;
import de.adito.ojcms.transactions.annotations.Transactional;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import java.util.logging.Logger;

import static de.adito.ojcms.rest.security.user.OJUser.DISPLAY_NAME;

/**
* Test business to test the additionally added persistent bean type.
Expand All @@ -14,12 +19,18 @@
@ApplicationScoped
class SomeTestBusiness
{
private static final Logger LOGGER = Logger.getLogger(SomeTestBusiness.class.getName());

@Inject
private IBeanContainer<SomeAdditionalTestBean> additionalBeans;
@Inject
private UserRequestContext userRequestContext;

@Transactional
void doIt()
{
final OJUser requestingUser = userRequestContext.getRequestingUser();
LOGGER.info("Requesting user for business: " + requestingUser.getValue(DISPLAY_NAME));
additionalBeans.addBean(new SomeAdditionalTestBean());
}
}

0 comments on commit 344674e

Please sign in to comment.