diff --git a/lib/src/main/java/com/auth0/msg/AbstractMessage.java b/lib/src/main/java/com/auth0/msg/AbstractMessage.java new file mode 100644 index 00000000..372fd17d --- /dev/null +++ b/lib/src/main/java/com/auth0/msg/AbstractMessage.java @@ -0,0 +1,189 @@ +package com.auth0.msg; + +import com.auth0.jwt.algorithms.Algorithm; +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collections; +import java.util.List; +import java.util.Map; + +/** + * This abstract class provides basic processing of messages + */ +public abstract class AbstractMessage implements Message { + private Map claims; + private String input; + private Error error = null; + private boolean verified = false; + ObjectMapper mapper = new ObjectMapper(); + + protected AbstractMessage(Map claims) { + this.claims = claims; + } + + /** + * @param input the urlEncoded String representation of a message + * @return a Message representation of the UrlEncoded string + */ + public Message fromUrlEncoded(String input) throws MalformedURLException, IOException { + AbstractMessage msg = mapper.readValue(new URL(input), AbstractMessage.class); + return msg; + } + + /** + * Takes the claims of this instance of the AbstractMessage class and serializes them + * to an urlEncoded string + * + * @return an urlEncoded string + */ + public String toUrlEncoded() throws SerializationException { + // TODO + // Serialize the content of this instance (the claims map) into an UrlEncoded string + return ""; + } + + /** + * Logic to extract from the JSON string the values + * + * @param input The JSON String representation of a message + * @return a Message representation of the Json + */ + public Message fromJson(String input) { + this.input = input; + try { + // Convert JSON string to Object + AbstractMessage msg = mapper.readValue(input, AbstractMessage.class); + return msg; + } catch (JsonGenerationException e) { + e.printStackTrace(); + } catch (JsonMappingException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + /** + * Takes the claims of this instance of the AbstractMessage class and serializes them + * to a json string + * + * @return a JSON String representation in the form of a hashMap mapping string -> string + */ + public String toJson() throws SerializationException { + if (this.error != null) { + //This should be custom exception + throw new InvalidClaimsException("Error present cannot serialize message"); + } + return ""; + } + + /** + * @param input the jwt String representation of a message + * @param Key that might contain the necessary key + * @return a Message representation of the JWT + */ + public Message fromJwt(String input, Key key) { + this.input = input; + //This will have logic to parse Jwt to claims + return this; + } + + /** + * @param input the jwt String representation of a message + * @param KeyJar that might contain the necessary key + * @return a Message representation of the JWT + */ + public Message fromJwt(String input, KeyJar jar) { + this.input = input; + //This will have logic to parse Jwt to claims + return this; + } + + /** + * Serialize the content of this instance (the claims map) into a jwt string + * @param KeyJar the signing keyjar + * @param String the algorithm to use in signing the JWT + * @return a jwt String + * @throws InvalidClaimsException + */ + public String toJwt(KeyJar keyjar, Algorithm algorithm) throws + InvalidClaimsException, SerializationException { + return null; + } + + /** + * Serialize the content of this instance (the claims map) into a jwt string + * @param Key the signing key + * @param String the algorithm to use in signing the JWT + * @return a jwt String + * @throws InvalidClaimsException + */ + public String toJwt(Key key, Algorithm algorithm) throws InvalidClaimsException, SerializationException { + return null; + } + + /** + * verify that the required claims are present + * @return whether the verification passed + */ + public boolean verify() { + //This method will set error if verification fails + return true; + } + + /** + * add the claim to this instance of message + * @param ClaimType the name of the claim + * @param Object the value of the claim to add to this instance of Message + * @return a Message representation of the Json + */ + public void addClaim(ClaimType name, Object value) { + // verify 'name’ is a valid claim and then check the type is valid before adding + } + + /** + * @param String endpoint to base the request url on + * @return a String for the representation of the formatted request + */ + public String getRequestWithEndpoint(String authorizationEndpoint) { + return null; + } + + /** + * @return Error an object representing the error status of claims verification + */ + public Error getError() { + return error; + } + + /** + * @return List of the list of claims for this messsage + */ + public Map getClaims(){ + return this.claims; + } + + /** + * @return List of the list of standard optional claims for this messsage type + */ + protected List getOptionalClaims(){ + return Collections.emptyList(); + } + + /** + * @return List of the list of standard required claims for this messsage type + */ + abstract protected List getRequiredClaims(); + + @Override + public String toString() { + //Override to return user friendly value + return super.toString(); + } +} diff --git a/lib/src/main/java/com/auth0/msg/AlgorithmEnum.java b/lib/src/main/java/com/auth0/msg/AlgorithmEnum.java new file mode 100644 index 00000000..77dc325f --- /dev/null +++ b/lib/src/main/java/com/auth0/msg/AlgorithmEnum.java @@ -0,0 +1,14 @@ +package com.auth0.msg; + +/** + * This enum specifies the encryption and signing algorithm type + */ +public enum AlgorithmEnum { + RS256, + RS384, + RS512, + HS256, + HS384, + HS512, + ES256; +} diff --git a/lib/src/main/java/com/auth0/msg/ClaimType.java b/lib/src/main/java/com/auth0/msg/ClaimType.java new file mode 100644 index 00000000..aabc4c2d --- /dev/null +++ b/lib/src/main/java/com/auth0/msg/ClaimType.java @@ -0,0 +1,21 @@ +package com.auth0.msg; + +import java.util.Arrays; +import java.util.List; + +/** + * This enum specifies the claims and their allowed values to allow for validation of messages + */ +public enum ClaimType { + + GRANT_TYPE("grant_type", Arrays.asList("refresh_token")), + ERROR("error", Arrays.asList("invalid_request", "unauthorized_client")); + + private final String name; + private final List allowedValues; + + ClaimType(String name, List allowedValues) { + this.name = name; + this.allowedValues = allowedValues; + } +} \ No newline at end of file diff --git a/lib/src/main/java/com/auth0/msg/DataLocation.java b/lib/src/main/java/com/auth0/msg/DataLocation.java new file mode 100644 index 00000000..d49f9047 --- /dev/null +++ b/lib/src/main/java/com/auth0/msg/DataLocation.java @@ -0,0 +1,8 @@ +package com.auth0.msg; + +/** + * This enum specifies whether the data will be placed in a fragment or in a query part + */ +public enum DataLocation { + FRAGMENT, QUERY_STRING, FORM_POST +} diff --git a/lib/src/main/java/com/auth0/msg/InvalidClaimsException.java b/lib/src/main/java/com/auth0/msg/InvalidClaimsException.java new file mode 100644 index 00000000..acd83ef7 --- /dev/null +++ b/lib/src/main/java/com/auth0/msg/InvalidClaimsException.java @@ -0,0 +1,14 @@ +package com.auth0.msg; + +/** + * A runtime exception that is thrown when there is an invalid claim in a Message object type + */ +public class InvalidClaimsException extends RuntimeException { + public InvalidClaimsException(String message) { + this(message, null); + } + + public InvalidClaimsException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/lib/src/main/java/com/auth0/msg/Jwk.java b/lib/src/main/java/com/auth0/msg/Jwk.java new file mode 100644 index 00000000..5aac2c3e --- /dev/null +++ b/lib/src/main/java/com/auth0/msg/Jwk.java @@ -0,0 +1,8 @@ +package com.auth0.msg; + +public class Jwk { + public Key importPrivateRsaKeyFromFile(String filename){ + // TODO + return new Key(); + } +} \ No newline at end of file diff --git a/lib/src/main/java/com/auth0/msg/Key.java b/lib/src/main/java/com/auth0/msg/Key.java new file mode 100644 index 00000000..590c598f --- /dev/null +++ b/lib/src/main/java/com/auth0/msg/Key.java @@ -0,0 +1,4 @@ +package com.auth0.msg; + +public class Key { +} \ No newline at end of file diff --git a/lib/src/main/java/com/auth0/msg/KeyBundle.java b/lib/src/main/java/com/auth0/msg/KeyBundle.java new file mode 100644 index 00000000..e8a78114 --- /dev/null +++ b/lib/src/main/java/com/auth0/msg/KeyBundle.java @@ -0,0 +1,4 @@ +package com.auth0.msg; + +public class KeyBundle { +} diff --git a/lib/src/main/java/com/auth0/msg/KeyJar.java b/lib/src/main/java/com/auth0/msg/KeyJar.java new file mode 100644 index 00000000..2861df31 --- /dev/null +++ b/lib/src/main/java/com/auth0/msg/KeyJar.java @@ -0,0 +1,7 @@ +package com.auth0.msg; + +public class KeyJar { + public void addKeyBundle(String owner, KeyBundle kb) { + // TODO + } +} diff --git a/lib/src/main/java/com/auth0/msg/Message.java b/lib/src/main/java/com/auth0/msg/Message.java new file mode 100644 index 00000000..49f03d9f --- /dev/null +++ b/lib/src/main/java/com/auth0/msg/Message.java @@ -0,0 +1,110 @@ +package com.auth0.msg; + +import com.auth0.jwt.algorithms.Algorithm; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.util.Map; + +/** + * This interface all the methods related to message processing. + */ +public interface Message { + + /** + * Serialize the content of this instance (the claims map) into a JSON object + * @return a JSON String representation of the message + * @throws SerializationException + */ + String toJson() throws SerializationException; + + /** + * Serialize the content of the claims map into an UrlEncoded string + * @return a urlEncoded string + * @throws SerializationException + */ + String toUrlEncoded() throws SerializationException; + + /** + * Serialize the content of this instance (the claims map) into a jwt string + * @param Key the signing key + * @param String the algorithm to use in signing the JWT + * @return a jwt String + * @throws InvalidClaimsException + */ + String toJwt(Key key, Algorithm algorithm) throws InvalidClaimsException, SerializationException; + + /** + * Serialize the content of this instance (the claims map) into a jwt string + * @param KeyJar the signing keyjar + * @param String the algorithm to use in signing the JWT + * @return a jwt String + * @throws InvalidClaimsException + */ + String toJwt(KeyJar jar, Algorithm algorithm) throws InvalidClaimsException, SerializationException; + + /** + * Logic to extract from the string the values + * @param input The JSON String representation of a message + * @return a Message representation of the Json + */ + Message fromJson(String input); + + /** + * @param input the urlEncoded String representation of a message + * @return a Message representation of the UrlEncoded string + */ + Message fromUrlEncoded(String input) throws MalformedURLException, IOException; + + /** + * + * @param input the jwt String representation of a message + * @param key that might contain the necessary key + * @return a Message representation of the JWT + */ + Message fromJwt(String input, Key key); + + /** + * + * @param input the jwt String representation of a message + * @param KeyJar that might contain the necessary key + * @return a Message representation of the JWT + */ + Message fromJwt(String input, KeyJar jar); + + /** + * verify that the required claims are present + * @return whether the verification passed + */ + boolean verify(); + + /** + * + * @param name of the claim + * @param value of the claim + */ + void addClaim(ClaimType name, Object value); + + /** + * + * @return Map of claims + * @throws InvalidClaimsException + */ + Map getClaims() throws InvalidClaimsException; + + /** + * + * @param String authorization endpoint + */ + String getRequestWithEndpoint(String authorizationEndpoint, DataLocation location); + + /** + * @return the error object representing an error in verification + */ + Error getError(); + + /** + * @return boolean for whether there is an error in verification + */ + boolean hasError(); +} diff --git a/lib/src/main/java/com/auth0/msg/MessageUtil.java b/lib/src/main/java/com/auth0/msg/MessageUtil.java new file mode 100644 index 00000000..b8b6ab83 --- /dev/null +++ b/lib/src/main/java/com/auth0/msg/MessageUtil.java @@ -0,0 +1,19 @@ +package com.auth0.msg; + +import java.util.HashMap; +import java.util.Map; + +public class MessageUtil { + /** + * Returns a hashmap representation of the contents of the urlEncoded string + * which is passed in as a parameter + * + * @param urlEncoded the urlEncoded String representation of a message + * @return a map of the key value pairs encoded in the string parameter + */ + public static Map claimsFromUrlEncoded(String urlEncoded) throws Exception { + //Logic to extract from the string the values + Map values = new HashMap(); + return values; + } +} diff --git a/lib/src/main/java/com/auth0/msg/ProviderConfigurationResponse.java b/lib/src/main/java/com/auth0/msg/ProviderConfigurationResponse.java new file mode 100644 index 00000000..81b537fd --- /dev/null +++ b/lib/src/main/java/com/auth0/msg/ProviderConfigurationResponse.java @@ -0,0 +1,31 @@ +package com.auth0.msg; + +import java.util.List; +import java.util.Map; + +public class ProviderConfigurationResponse extends AbstractMessage{ + + public ProviderConfigurationResponse(Map claims){ + super(claims); + } + + @Override + protected List getRequiredClaims() { + return null; + } + + @Override + public Map getClaims() throws InvalidClaimsException { + return null; + } + + @Override + public String getRequestWithEndpoint(String authorizationEndpoint, DataLocation location) { + return null; + } + + @Override + public boolean hasError() { + return false; + } +} diff --git a/lib/src/main/java/com/auth0/msg/RSAKey.java b/lib/src/main/java/com/auth0/msg/RSAKey.java new file mode 100644 index 00000000..38e92259 --- /dev/null +++ b/lib/src/main/java/com/auth0/msg/RSAKey.java @@ -0,0 +1,4 @@ +package com.auth0.msg; + +public class RSAKey { +} \ No newline at end of file diff --git a/lib/src/main/java/com/auth0/msg/RegistrationRequest.java b/lib/src/main/java/com/auth0/msg/RegistrationRequest.java new file mode 100644 index 00000000..e1c4fed7 --- /dev/null +++ b/lib/src/main/java/com/auth0/msg/RegistrationRequest.java @@ -0,0 +1,31 @@ +package com.auth0.msg; + +import java.util.List; +import java.util.Map; + +public class RegistrationRequest extends AbstractMessage{ + + public RegistrationRequest(Map claims){ + super(claims); + } + + @Override + protected List getRequiredClaims() { + return null; + } + + @Override + public Map getClaims() throws InvalidClaimsException { + return null; + } + + @Override + public String getRequestWithEndpoint(String authorizationEndpoint, DataLocation location) { + return null; + } + + @Override + public boolean hasError() { + return false; + } +} diff --git a/lib/src/main/java/com/auth0/msg/RegistrationResponse.java b/lib/src/main/java/com/auth0/msg/RegistrationResponse.java new file mode 100644 index 00000000..7fb5fe89 --- /dev/null +++ b/lib/src/main/java/com/auth0/msg/RegistrationResponse.java @@ -0,0 +1,31 @@ +package com.auth0.msg; + +import java.util.List; +import java.util.Map; + +public class RegistrationResponse extends AbstractMessage{ + + public RegistrationResponse(Map claims){ + super(claims); + } + + @Override + protected List getRequiredClaims() { + return null; + } + + @Override + public Map getClaims() throws InvalidClaimsException { + return null; + } + + @Override + public String getRequestWithEndpoint(String authorizationEndpoint, DataLocation location) { + return null; + } + + @Override + public boolean hasError() { + return false; + } +} diff --git a/lib/src/main/java/com/auth0/msg/SerializationException.java b/lib/src/main/java/com/auth0/msg/SerializationException.java new file mode 100644 index 00000000..3f0a6da1 --- /dev/null +++ b/lib/src/main/java/com/auth0/msg/SerializationException.java @@ -0,0 +1,14 @@ +package com.auth0.msg; + +/** + * A runtime exception that is thrown when there is an issue with serialization of the Message type + */ +public class SerializationException extends RuntimeException { + public SerializationException(String message) { + this(message, null); + } + + public SerializationException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/lib/src/test/java/org/oidc/message/AbstractMessageTest.java b/lib/src/test/java/org/oidc/message/AbstractMessageTest.java new file mode 100644 index 00000000..22a4817a --- /dev/null +++ b/lib/src/test/java/org/oidc/message/AbstractMessageTest.java @@ -0,0 +1,5 @@ +package com.auth0.msg; + +public class AbstractMessageTest { + +}