Skip to content

Commit

Permalink
Remove non native working bits, alter logging.
Browse files Browse the repository at this point in the history
  • Loading branch information
BarDweller committed Jun 28, 2022
1 parent 889e69c commit 3f95420
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public void filter(ClientRequestContext requestContext) throws IOException {
SignedRequestMap headers = new SignedRequestMap.MVSO_StringMap(requestContext.getHeaders());
SignedRequestMap parameters = new SignedRequestMap.QueryParameterMap(requestContext.getUri().getRawQuery());

SignedRequestFeature.writeLog(Level.FINEST, this, "REQUEST FILTER: USER={0}, PATH={1}, QUERY={2}, HEADERS={3}, HAS_ENTITY={4}",
SignedLogger.writeLog(Level.FINEST, this, "REQUEST FILTER: USER={0}, PATH={1}, QUERY={2}, HEADERS={3}, HAS_ENTITY={4}",
userId,
requestContext.getMethod() + " " + requestContext.getUri().getRawPath(),
requestContext.getUri().getRawQuery(),
Expand Down Expand Up @@ -120,7 +120,7 @@ public void filter(ClientRequestContext requestContext) throws IOException {
e, Response.Status.INTERNAL_SERVER_ERROR);
}

SignedRequestFeature.writeLog(Level.FINEST, this, "CLIENT FILTER: {0} {1} {2}", invalidHmacEx, clientHmac, headers);
SignedLogger.writeLog(Level.FINEST, this, "CLIENT FILTER: {0} {1} {2}", invalidHmacEx, clientHmac, headers);

if ( invalidHmacEx != null ) {
// STOP!! turn this right around with the bad response
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public SignedContainerRequestFilter(SignedRequestSecretProvider playerClient, Si
this.timedCache = timedCache;

if ( playerClient == null || timedCache == null ) {
SignedRequestFeature.writeLog(Level.SEVERE, this,
SignedLogger.writeLog(Level.SEVERE, this,
"Required resources are not available: playerClient={0}, timedCache={1}",
playerClient, timedCache);
throw new IllegalStateException("Required resources are not available");
Expand All @@ -70,13 +70,14 @@ public SignedContainerRequestFilter(SignedRequestSecretProvider playerClient, Si
*/
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {

WebApplicationException invalidHmacEx = null;
SignedRequestHmac hmac = null;

String userId = requestContext.getHeaderString(SignedRequestHmac.GAMEON_ID);
String method = requestContext.getMethod();

SignedRequestFeature.writeLog(Level.FINEST, this, "REQUEST FILTER: USER={0}, PATH={1}, QUERY={2}, HEADERS={3}",
SignedLogger.writeLog(Level.FINEST, this, "REQUEST FILTER: USER={0}, PATH={1}, QUERY={2}, HEADERS={3}",
userId,
method + " " + requestContext.getUriInfo().getAbsolutePath().getRawPath(),
requestContext.getUriInfo().getQueryParameters(false),
Expand All @@ -86,23 +87,25 @@ public void filter(ContainerRequestContext requestContext) throws IOException {
if ( "GET".equals(method) ) {
// no validation required for GET requests. If an ID isn't provided,
// then we won't do validation and will just return.
SignedRequestFeature.writeLog(Level.FINEST, this, "FILTER: GET WITH NO ID-- NO VERIFICATION");
SignedLogger.writeLog(Level.FINEST, this, "FILTER: GET WITH NO ID-- NO VERIFICATION");
return;
} else {
//debug empty userid header..
if(userId!=null){
BufferedReader buffer = new BufferedReader(new InputStreamReader(requestContext.getEntityStream(), SignedRequestHmac.UTF8));
String body = buffer.lines().collect(Collectors.joining("\n"));
SignedRequestFeature.writeLog(Level.FINEST,this,"BODY: "+body);
SignedLogger.writeLog(Level.FINEST,this,"BODY: "+body);
}

SignedRequestFeature.writeLog(Level.FINEST, this, "FILTER: "+method+" WITH NO ID-- UNAUTHORIZED");
SignedLogger.writeLog(Level.FINEST, this, "FILTER: "+method+" WITH NO ID-- UNAUTHORIZED");
// STOP!! turn this right around with the bad response
requestContext.abortWith(Response.status(Status.FORBIDDEN).build());
return;
}
}

SignedLogger.writeLog(Level.FINEST, this, "FILTER: ID PRESENT.. VALIDATING...");

try {
SignedRequestMap headers = new SignedRequestMap.MVSS_StringMap(requestContext.getHeaders());
SignedRequestMap query = new SignedRequestMap.MVSS_StringMap(requestContext.getUriInfo().getQueryParameters(false));
Expand All @@ -121,7 +124,9 @@ public void filter(ContainerRequestContext requestContext) throws IOException {
// @see SignedReaderInterceptor as assigned by SignedRequestFeature
requestContext.setProperty("SignedRequestHmac", hmac);
} else {
SignedLogger.writeLog(Level.FINEST, this, "FILTER: verifying hmac");
hmac.verifyFullSignature();
SignedLogger.writeLog(Level.FINEST, this, "FILTER: hmac verified");
}
} catch(WebApplicationException ex) {
invalidHmacEx = ex;
Expand All @@ -131,9 +136,11 @@ public void filter(ContainerRequestContext requestContext) throws IOException {
}

requestContext.setProperty("player.id", userId);
SignedRequestFeature.writeLog(Level.FINEST, this, "FILTER: {0} {1}", invalidHmacEx, hmac);
SignedLogger.writeLog(Level.FINEST, this, "FILTER: {0} {1}", invalidHmacEx, hmac);

if ( invalidHmacEx != null ) {
invalidHmacEx.printStackTrace();

// STOP!! turn this right around with the bad response
requestContext.abortWith(invalidHmacEx.getResponse());
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/gameontext/signed/SignedJWT.java
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ private AuthenticationState processSources(PublicKey key, String[] sources) {
code = FailureCode.NONE;
} catch (ParseException e) {
code = FailureCode.BAD_SIGNATURE;
SignedRequestFeature.writeLog(Level.WARNING, this, "JWT failed validation {0}. {1}", e.getMessage(), token);
SignedLogger.writeLog(Level.WARNING, this, "JWT failed validation {0}. {1}", e.getMessage(), token);
}
}

Expand Down
6 changes: 2 additions & 4 deletions src/main/java/org/gameontext/signed/SignedJWTValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package org.gameontext.signed;

import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.security.cert.Certificate;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
Expand All @@ -33,14 +32,13 @@
import javax.enterprise.context.ApplicationScoped;

import org.eclipse.microprofile.config.ConfigProvider;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.InvalidJwtException;

import io.smallrye.jwt.auth.principal.JWTCallerPrincipal;
import io.quarkus.arc.Unremovable;
import io.smallrye.jwt.build.Jwt;
import io.smallrye.jwt.build.JwtClaimsBuilder;

@ApplicationScoped
@Unremovable
public class SignedJWTValidator {


Expand Down
29 changes: 29 additions & 0 deletions src/main/java/org/gameontext/signed/SignedLogger.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.gameontext.signed;

import java.util.logging.Level;
import java.util.logging.Logger;

public class SignedLogger {

final static Logger logger = Logger.getLogger("org.gameontext.signed");

final static void writeLog(Level level, Object source, String message, Object... args) {

//hack hack.. can't enable FINEST for native apps??!!
if(level.equals(Level.FINEST))level = Level.FINER;

if (logger.isLoggable(level)) {
logger.logp(level, source.getClass().getName(), "", message, args);
}
}

final static void writeLog(Level level, Object source, String message, Throwable thrown) {

//hack hack.. can't enable FINEST for native apps??!!
if(level.equals(Level.FINEST))level = Level.FINER;

if (logger.isLoggable(level)) {
logger.logp(level, source.getClass().getName(), "", message, thrown);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ public Object aroundReadFrom(ReaderInterceptorContext context) throws IOExceptio
SignedRequestHmac hmac = (SignedRequestHmac) context.getProperty("SignedRequestHmac");

if ( hmac != null ) {
// Fully read request body

// Fully read request body
BufferedReader buffer = new BufferedReader(new InputStreamReader(context.getInputStream(), SignedRequestHmac.UTF8));
String body = buffer.lines().collect(Collectors.joining("\n"));
byte[] bodyBytes = body.getBytes(SignedRequestHmac.UTF8);
Expand All @@ -55,7 +55,7 @@ public Object aroundReadFrom(ReaderInterceptorContext context) throws IOExceptio
// what we read...
context.setInputStream(new ByteArrayInputStream(bodyBytes));
}
SignedRequestFeature.writeLog(Level.FINEST, this, "READER INTERCEPTOR: {0} {1}", hmac);
SignedLogger.writeLog(Level.FINEST, this, "READER INTERCEPTOR: {0} {1}", hmac);
}
return context.proceed();
}
Expand Down
28 changes: 6 additions & 22 deletions src/main/java/org/gameontext/signed/SignedRequestFeature.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@
*******************************************************************************/
package org.gameontext.signed;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.spi.CDI;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
Expand All @@ -27,39 +23,27 @@
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.ext.Provider;

import io.quarkus.arc.Unremovable;

@Provider
@ApplicationScoped
@Unremovable
public class SignedRequestFeature implements DynamicFeature {

final static Logger logger = Logger.getLogger("org.gameontext.signed");

final static void writeLog(Level level, Object source, String message, Object... args) {
if (logger.isLoggable(level)) {
logger.logp(level, source.getClass().getName(), "", message, args);
}
}

final static void writeLog(Level level, Object source, String message, Throwable thrown) {
if (logger.isLoggable(level)) {
logger.logp(level, source.getClass().getName(), "", message, thrown);
}
}

SignedRequestSecretProvider playerClient;
SignedRequestTimedCache timedCache;

public SignedRequestFeature() {
// TODO: Bug in Liberty: @Inject does not work (jax-rs creates its own instance)
// work-around is to lookup the CDI beans directly
//provider/dynamicfeature isn't a cdi target, so cannot inject beans here, have to lookup programmatically
playerClient = CDI.current().select(SignedRequestSecretProvider.class).get();
timedCache = CDI.current().select(SignedRequestTimedCache.class).get();
}

@Override
public void configure(ResourceInfo resourceInfo, FeatureContext context) {
SignedRequest sr = resourceInfo.getResourceMethod().getAnnotation(SignedRequest.class);
if ( sr == null )
if ( sr == null ){
return;
}

context.register(new SignedContainerRequestFilter(playerClient, timedCache));

Expand Down
35 changes: 14 additions & 21 deletions src/main/java/org/gameontext/signed/SignedRequestTimedCache.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,13 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;

import javax.annotation.Resource;
import javax.enterprise.concurrent.ManagedExecutorService;
import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class SignedRequestTimedCache implements Runnable {
import io.quarkus.arc.Unremovable;

@Resource
ManagedExecutorService managedExecutorService;
@ApplicationScoped
@Unremovable
public class SignedRequestTimedCache {

/** number of requests before a cleanup is triggered */
final static int TRIGGER_CLEANUP_DEPTH = 1000;
Expand All @@ -43,7 +41,16 @@ public boolean isDuplicate(String hmac, Duration expiresIn) {
// if the count is over or above the cutoff point, try to clean up expired sessions
// avoid using size() on concurrent maps.
if ( count >= TRIGGER_CLEANUP_DEPTH && triggerCount.compareAndSet(count, 0) ) {
managedExecutorService.execute(this);
SignedLogger.writeLog(Level.INFO,this,"Clearing expired hmacs");
for ( Entry<String, TimestampedKey> request : requests.entrySet() ) {
if ( request.getValue().hasExpired() ) {
requests.remove(request.getKey());
} else {
// ConcurrentSkipListMap keeps them in sorted order by time
// stop as soon as we find a not expired one.
break;
}
}
}

TimestampedKey t = new TimestampedKey(hmac, expiresIn);
Expand All @@ -55,18 +62,4 @@ public boolean isDuplicate(String hmac, Duration expiresIn) {
}
}

@Override
public void run() {
SignedRequestFeature.writeLog(Level.INFO,this,"Clearing expired hmacs");

for ( Entry<String, TimestampedKey> request : requests.entrySet() ) {
if ( request.getValue().hasExpired() ) {
requests.remove(request.getKey());
} else {
// ConcurrentSkipListMap keeps them in sorted order by time
// stop as soon as we find a not expired one.
break;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public void aroundWriteTo(WriterInterceptorContext context) throws IOException,
hmac.generateBodyHash(headers, body)
.signRequest(headers);

SignedRequestFeature.writeLog(Level.FINEST, this, "WRITER INTERCEPTOR: {0}", headers);
SignedLogger.writeLog(Level.FINEST, this, "WRITER INTERCEPTOR: {0}", headers);
} finally {
// Write the response
old.write(body);
Expand Down

0 comments on commit 3f95420

Please sign in to comment.