Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ $class=in.erail.route.LoadUserFromAccessTokenRouteBuillder

vertx=/io/vertx/core/Vertx
log=true
oAuth2Auth=/io/vertx/ext/auth/oauth2/OAuth2Auth
enable^=/in/erail/common/FrameworkConfiguration.oAuth2AuthEnable
userProvider=/in/erail/user/UserProvider
4 changes: 4 additions & 0 deletions config-layers/common/in/erail/user/UserProvider.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#/in/erail/user/UserProvider
$class=in.erail.user.oauth2.OAuth2AuthUserProvider

oAuth2Auth=/io/vertx/ext/auth/oauth2/OAuth2Auth
28 changes: 22 additions & 6 deletions src/main/java/in/erail/model/RequestEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.google.common.io.BaseEncoding;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.json.JsonObject;
import java.util.Map;

/**
Expand All @@ -23,9 +24,10 @@ public class RequestEvent {
private Map<String, String> mPathParameters;
private Map<String, String> mStageVariables;
@SuppressWarnings("rawtypes")
private Map mRequestContext;
private Map mRequestContext;
private byte[] mBody = new byte[0];
private boolean mIsBase64Encoded = false;
private Map<String, Object> mPrincipal;

public String getResource() {
return mResource;
Expand Down Expand Up @@ -100,12 +102,12 @@ public void setStageVariables(Map<String, String> pStageVariables) {
}

@SuppressWarnings("rawtypes")
public Map getRequestContext() {
public Map getRequestContext() {
return mRequestContext;
}

@SuppressWarnings("rawtypes")
public void setRequestContext(Map pRequestContext) {
public void setRequestContext(Map pRequestContext) {
this.mRequestContext = pRequestContext;
}

Expand All @@ -124,11 +126,25 @@ public byte[] getBody() {
public void setBody(byte[] pBody) {
this.mBody = pBody;
}
public String bodyAsString(){
if(isIsBase64Encoded()){

public String bodyAsString() {
if (isIsBase64Encoded()) {
return new String(BaseEncoding.base64().decode(new String(getBody())));
}
return new String(getBody());
}

public Map<String, Object> getPrincipal() {
return mPrincipal;
}

public void setPrincipal(Map<String, Object> pPrincipal) {
this.mPrincipal = pPrincipal;
}

@Override
public String toString() {
return JsonObject.mapFrom(this).toString();
}

}
16 changes: 9 additions & 7 deletions src/main/java/in/erail/model/ResponseEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.common.base.Preconditions;
import com.google.common.net.HttpHeaders;
import com.google.common.net.MediaType;
import io.vertx.core.json.JsonObject;
import io.vertx.reactivex.core.MultiMap;
import java.util.Arrays;
import java.util.Collections;
Expand Down Expand Up @@ -166,17 +167,18 @@ public ResponseEvent setContentType(MediaType pMediaType) {
return this;
}

public ResponseEvent addHeader(String pHeaderName, String pMediaType) {
mMultiValueHeaders.add(HttpHeaders.CONTENT_TYPE, pMediaType);
return this;
}

public ResponseEvent addHeader(String pHeaderName, MediaType pMediaType) {
addHeader(HttpHeaders.CONTENT_TYPE, pMediaType.toString());
public ResponseEvent addHeader(String pHeaderName, String pValue) {
mMultiValueHeaders.add(pHeaderName, pValue);
return this;
}

public String headerValue(String pHeaderName) {
return mMultiValueHeaders.get(pHeaderName);
}

@Override
public String toString() {
return JsonObject.mapFrom(this).toString();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,60 @@

import com.google.common.base.Strings;
import com.google.common.net.HttpHeaders;
import in.erail.user.UserProvider;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.oauth2.impl.OAuth2AuthProviderImpl;
import io.vertx.ext.auth.oauth2.impl.OAuth2TokenImpl;
import io.vertx.reactivex.ext.auth.oauth2.AccessToken;
import io.vertx.reactivex.ext.auth.oauth2.OAuth2Auth;
import io.vertx.reactivex.ext.web.Router;
import io.vertx.reactivex.ext.web.RoutingContext;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
*
* @author vinay
*/
public class LoadUserFromAccessTokenRouteBuillder extends AbstractRouterBuilderImpl {

private OAuth2Auth mOAuth2Auth;

public OAuth2Auth getOAuth2Auth() {
return mOAuth2Auth;
}

public void setOAuth2Auth(OAuth2Auth pOAuth2Auth) {
this.mOAuth2Auth = pOAuth2Auth;
}
private Pattern AUTH_TOKEN = Pattern.compile("^Bearer\\s(?<token>.*)");
private UserProvider mUserProvider;

@Override
public Router getRouter(Router pRouter) {
pRouter.route().handler(this::handle);
return pRouter;

}

public void handle(RoutingContext pRoutingContext) {

if (pRoutingContext.user() == null) {
String access_token = pRoutingContext.request().getHeader(HttpHeaders.AUTHORIZATION);
if (!Strings.isNullOrEmpty(access_token)) {
OAuth2AuthProviderImpl provider = (OAuth2AuthProviderImpl) getOAuth2Auth().getDelegate();
JsonObject accessToken = new JsonObject().put("access_token", access_token.split(" ")[1]);
try {
OAuth2TokenImpl token = new OAuth2TokenImpl(provider, accessToken);
pRoutingContext.setUser(new AccessToken(token));
} catch (RuntimeException e) {
getLog().error(e);
pRoutingContext.fail(401);
return;
Matcher token = AUTH_TOKEN.matcher(access_token);
if (token.find()) {
JsonObject accessToken = new JsonObject().put("access_token", token.group("token"));
try {
pRoutingContext
.setUser(getUserProvider()
.getUser(accessToken)
.blockingGet());
} catch (RuntimeException e) {
getLog().error(e);
pRoutingContext.fail(401);
return;
}
} else {
getLog().warn(() -> "Invalid Auth Header:" + access_token);
}
}
}
pRoutingContext.next();
}

public UserProvider getUserProvider() {
return mUserProvider;
}

public void setUserProvider(UserProvider pUserProvider) {
this.mUserProvider = pUserProvider;
}

}
11 changes: 9 additions & 2 deletions src/main/java/in/erail/route/OpenAPI3RouteBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ public JsonObject serialiseRoutingContext(RoutingContext pContext) {
request.setQueryStringParameters(convertMultiMapIntoMap(pContext.queryParams()));
request.setPathParameters(convertMultiMapIntoMap(pContext.request().params()));

JsonObject principal = Optional
.ofNullable(pContext.user())
.flatMap((t) -> Optional.ofNullable(t.principal()))
.orElse(new JsonObject());

request.setPrincipal(principal.getMap());

JsonObject result = JsonObject.mapFrom(request);

getLog().debug(() -> "Context to JSON:" + result.toString());
Expand All @@ -147,8 +154,8 @@ public HttpServerResponse buildResponseFromReply(JsonObject pReplyResponse, Rout

Optional<String> contentType = Optional.ofNullable(response.headerValue(HttpHeaders.CONTENT_TYPE));

if (contentType.isPresent()) {
response.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.OCTET_STREAM);
if (!contentType.isPresent()) {
response.setContentType(MediaType.OCTET_STREAM);
}

response
Expand Down
11 changes: 10 additions & 1 deletion src/main/java/in/erail/service/RESTServiceImpl.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package in.erail.service;

import com.google.common.net.MediaType;
import io.reactivex.schedulers.Schedulers;
import io.vertx.core.json.JsonObject;
import io.vertx.reactivex.core.Vertx;
import org.apache.logging.log4j.Logger;
import in.erail.glue.annotation.StartService;
import in.erail.model.RequestEvent;
import in.erail.model.ResponseEvent;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.reactivex.Scheduler;
import io.reactivex.Single;
import io.vertx.reactivex.core.eventbus.Message;
Expand Down Expand Up @@ -50,7 +52,14 @@ public Single<JsonObject> handleRequest(Message<JsonObject> pMessage) {
.flatMapMaybe(req -> process(req))
.toSingle(new ResponseEvent())
.map(resp -> JsonObject.mapFrom(resp))
.doOnSuccess(resp -> pMessage.reply(resp));
.doOnSuccess(resp -> pMessage.reply(resp))
.doOnError(err -> {
ResponseEvent resp = new ResponseEvent()
.setStatusCode(HttpResponseStatus.BAD_REQUEST.code())
.setContentType(MediaType.PLAIN_TEXT_UTF_8)
.setBody(ExceptionUtils.getMessage(err).getBytes());
pMessage.reply(JsonObject.mapFrom(resp));
});
}

@Override
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/in/erail/user/UserProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package in.erail.user;

import io.reactivex.Maybe;
import io.vertx.core.json.JsonObject;
import io.vertx.reactivex.ext.auth.User;

/**
*
* @author vinay
*/
public interface UserProvider {

default Maybe<User> getUser(JsonObject pPrincipal) {
return Maybe.empty();
}
}
35 changes: 35 additions & 0 deletions src/main/java/in/erail/user/oauth2/OAuth2AuthUserProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package in.erail.user.oauth2;

import in.erail.user.UserProvider;
import io.reactivex.Maybe;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.auth.oauth2.impl.OAuth2AuthProviderImpl;
import io.vertx.ext.auth.oauth2.impl.OAuth2TokenImpl;
import io.vertx.reactivex.ext.auth.User;
import io.vertx.reactivex.ext.auth.oauth2.AccessToken;
import io.vertx.reactivex.ext.auth.oauth2.OAuth2Auth;

/**
*
* @author vinay
*/
public class OAuth2AuthUserProvider implements UserProvider {

private OAuth2Auth mOAuth2Auth;

@Override
public Maybe<User> getUser(JsonObject pPrincipal) {
OAuth2AuthProviderImpl provider = (OAuth2AuthProviderImpl) getOAuth2Auth().getDelegate();
OAuth2TokenImpl token = new OAuth2TokenImpl(provider, pPrincipal);
return Maybe.just(new AccessToken(token));
}

public OAuth2Auth getOAuth2Auth() {
return mOAuth2Auth;
}

public void setOAuth2Auth(OAuth2Auth pOAuth2Auth) {
this.mOAuth2Auth = pOAuth2Auth;
}

}
3 changes: 1 addition & 2 deletions src/test/java/in/erail/service/BinaryBodyService.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package in.erail.service;

import com.google.common.base.Strings;
import com.google.common.net.HttpHeaders;
import com.google.common.net.MediaType;

import in.erail.model.RequestEvent;
Expand All @@ -28,7 +27,7 @@ public Maybe<ResponseEvent> process(RequestEvent pRequest) {
}

ResponseEvent response = new ResponseEvent();
response.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.PLAIN_TEXT_UTF_8);
response.setContentType(MediaType.PLAIN_TEXT_UTF_8);

JsonObject jsonBody = new JsonObject(Buffer.buffer(pRequest.getBody()));

Expand Down
8 changes: 4 additions & 4 deletions src/test/java/in/erail/service/BroadcastService.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package in.erail.service;

import com.google.common.base.Strings;
import com.google.common.net.HttpHeaders;
import com.google.common.net.MediaType;
import in.erail.test.TestConstants;
import io.vertx.core.json.JsonObject;

import in.erail.model.RequestEvent;
import in.erail.model.ResponseEvent;
import in.erail.test.TestConstants;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.reactivex.Maybe;
import io.vertx.core.json.JsonObject;

/**
*
Expand All @@ -35,7 +35,7 @@ public Maybe<ResponseEvent> process(RequestEvent pRequest) {

ResponseEvent response = new ResponseEvent();
response.setBody(TestConstants.Service.Message.successMessage().toString().getBytes());
response.addHeader(HttpHeaders.CONTENT_TYPE, MediaType.JSON_UTF_8);
response.setContentType(MediaType.JSON_UTF_8);

return Maybe.just(response);
}
Expand Down