-
Notifications
You must be signed in to change notification settings - Fork 72
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add classes for inbound identity #2197
- Loading branch information
1 parent
5357f1c
commit 96a5d90
Showing
12 changed files
with
650 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package io.jans.inbound; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.function.UnaryOperator; | ||
|
||
/** | ||
* Fields of this class can be referenced in the config properties of flow ExternalSiteLogin | ||
* (see the flow docs). If you are placing this file in the 'scripts' directory of Agama to avoid | ||
* server restarts, insert an instruction like <code>Call io.jans.inbound.CustomMappings#class</code> | ||
* at the beginning of the flow's code for changes in this class to take effect immediately. When | ||
* you are done, comment/remove the instruction and optionally put the final version of this class | ||
* in a jar file under 'custom/libs' directory | ||
*/ | ||
public final class CustomMappings { | ||
|
||
public static final UnaryOperator<Map<String, Object>> SAMPLE_MAPPING = | ||
|
||
profile -> { | ||
Map<String, Object> map = new HashMap<>(); | ||
//Fill your map as desired with data from input profile. See examples in io.jans.inbound.Mappings | ||
//value = profile.get("...") | ||
//map.put(Attrs.UID, ... ); | ||
return map; | ||
}; | ||
|
||
private CustomMappings() { } | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
|
||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<artifactId>agama-inbound</artifactId> | ||
<packaging>jar</packaging> | ||
<!--name>Supporting classes for inbound identity using Agama flows</name--> | ||
|
||
<parent> | ||
<groupId>io.jans</groupId> | ||
<artifactId>agama</artifactId> | ||
<version>1.0.2-SNAPSHOT</version> | ||
</parent> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
<maven.compiler.source>11</maven.compiler.source> | ||
<maven.compiler.target>11</maven.compiler.target> | ||
</properties> | ||
|
||
<repositories> | ||
<repository> | ||
<id>jans</id> | ||
<name>Jans repository</name> | ||
<url>https://maven.jans.io/maven</url> | ||
</repository> | ||
</repositories> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-assembly-plugin</artifactId> | ||
<version>3.4.2</version> | ||
<configuration> | ||
<descriptorRefs> | ||
<descriptorRef>jar-with-dependencies</descriptorRef> | ||
</descriptorRefs> | ||
</configuration> | ||
<executions> | ||
<execution> | ||
<id>make-assembly</id> | ||
<phase>package</phase> | ||
<goals> | ||
<goal>single</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
<dependencies> | ||
|
||
<!-- SERVLET --> | ||
<dependency> | ||
<groupId>jakarta.servlet</groupId> | ||
<artifactId>jakarta.servlet-api</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
|
||
<!-- JAX-RS --> | ||
<dependency> | ||
<groupId>org.jboss.spec.javax.ws.rs</groupId> | ||
<artifactId>jboss-jaxrs-api_3.0_spec</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>io.jans</groupId> | ||
<artifactId>jans-core-util</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>io.jans</groupId> | ||
<artifactId>jans-core-service</artifactId> | ||
<scope>provided</scope> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>com.nimbusds</groupId> | ||
<artifactId>oauth2-oidc-sdk</artifactId> | ||
<version>9.41</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.nimbusds</groupId> | ||
<artifactId>nimbus-jose-jwt</artifactId> | ||
<!-- already in jans-auth war --> | ||
<scope>provided</scope> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package io.jans.inbound; | ||
|
||
/** | ||
* This class provides constants for the most commonly used attribute names in Janssen Server database | ||
*/ | ||
public final class Attrs { | ||
|
||
private Attrs() { } | ||
|
||
public static final String UID = "uid"; | ||
public static final String MAIL = "mail"; | ||
public static final String CN = "cn"; | ||
public static final String DISPLAY_NAME = "displayName"; | ||
public static final String GIVEN_NAME = "givenName"; | ||
public static final String SN = "sn"; | ||
|
||
} |
77 changes: 77 additions & 0 deletions
77
agama/inboundID/src/main/java/io/jans/inbound/IdentityProcessor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
package io.jans.inbound; | ||
|
||
import java.lang.reflect.Field; | ||
import java.util.Arrays; | ||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.function.UnaryOperator; | ||
|
||
public class IdentityProcessor { | ||
|
||
private Provider provider; | ||
private UnaryOperator<Map<String, Object>> mapping; | ||
|
||
public IdentityProcessor(Provider provider, ClassLoader classLoader) | ||
throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { | ||
|
||
this.provider = provider; | ||
this.mapping = getMapping(provider.getMappingClassField(), | ||
classLoader == null ? getClass().getClassLoader() : classLoader); | ||
|
||
} | ||
|
||
public Map<String, List<Object>> applyMapping(Map<String, Object> profile) { | ||
|
||
Map<String, Object> pr = mapping.apply(profile); | ||
Map<String, List<Object>> res = new HashMap<>(); | ||
|
||
for (String key: pr.keySet()) { | ||
Object value = pr.get(key); | ||
|
||
if (key != null && value != null) { | ||
List<Object> newValue; | ||
|
||
if (value.getClass().isArray()) { | ||
newValue = Arrays.asList(value); | ||
} else if (Collection.class.isInstance(value)) { | ||
newValue = new ArrayList<>((Collection) value); | ||
} else { | ||
newValue = Collections.singletonList(value); | ||
} | ||
res.put(key, newValue); | ||
} | ||
} | ||
return res; | ||
|
||
} | ||
|
||
public String process(Map<String, List<?>> profile) throws Exception { | ||
//Provisions the user and returns its local id (inum) | ||
//reject if there are null values | ||
return null; | ||
} | ||
|
||
private UnaryOperator<Map<String, Object>> getMapping(String field, ClassLoader clsLoader) | ||
throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException { | ||
|
||
int i = 0; | ||
boolean valid = field != null; | ||
|
||
if (valid) { | ||
i = field.lastIndexOf("."); | ||
valid = i > 0 && i < field.length() - 1; | ||
} | ||
if (!valid) throw new IllegalAccessException("Unexpected value passed for mapping field: " + field); | ||
|
||
String clsName = field.substring(0, i); | ||
Class<?> cls = clsLoader.loadClass(clsName); | ||
Field f = cls.getDeclaredField(field.substring(i + 1)); | ||
return (UnaryOperator<Map<String, Object>>) f.get(cls); | ||
|
||
} | ||
|
||
} |
56 changes: 56 additions & 0 deletions
56
agama/inboundID/src/main/java/io/jans/inbound/Mappings.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package io.jans.inbound; | ||
|
||
import java.util.function.UnaryOperator; | ||
import java.util.Map; | ||
|
||
/** | ||
* Fields of this class can be referenced in the config properties of flow ExternalSiteLogin | ||
* (see the flow docs). | ||
*/ | ||
public final class Mappings { | ||
|
||
public static final UnaryOperator<Map<String, Object>> | ||
|
||
GOOGLE = profile -> Map.of( | ||
Attrs.UID, "google-" + profile.get("sub"), | ||
Attrs.MAIL, profile.get("email"), | ||
Attrs.CN, profile.get("name"), | ||
Attrs.SN, profile.get("family_name"), | ||
Attrs.DISPLAY_NAME, profile.get("given_name"), | ||
Attrs.GIVEN_NAME, profile.get("given_name") | ||
); | ||
|
||
public static final UnaryOperator<Map<String, Object>> | ||
//See https://developers.facebook.com/docs/graph-api/reference/user | ||
|
||
FACEBOOK = profile -> Map.of( | ||
Attrs.UID, "facebook-" + profile.get("id"), | ||
Attrs.MAIL, profile.get("email"), | ||
Attrs.CN, profile.get("name"), | ||
Attrs.SN, profile.get("last_name"), | ||
Attrs.DISPLAY_NAME, profile.get("first_name"), | ||
Attrs.GIVEN_NAME, profile.get("first_name") | ||
); | ||
|
||
public static final UnaryOperator<Map<String, Object>> | ||
|
||
APPLE = profile -> Map.of( | ||
Attrs.UID, "apple-" + profile.get("sub"), | ||
Attrs.MAIL, profile.get("email"), | ||
Attrs.DISPLAY_NAME, profile.get("name"), | ||
Attrs.GIVEN_NAME, profile.get("name") | ||
); | ||
|
||
public static final UnaryOperator<Map<String, Object>> | ||
//See https://docs.github.com/en/rest/users/users | ||
|
||
GITHUB = profile -> Map.of( | ||
Attrs.UID, "github-" + profile.getOrDefault("login", profile.get("id")), | ||
Attrs.MAIL, profile.get("email"), | ||
Attrs.DISPLAY_NAME, profile.get("name"), | ||
Attrs.GIVEN_NAME, profile.get("name") | ||
); | ||
|
||
private Mappings() { } | ||
|
||
} |
79 changes: 79 additions & 0 deletions
79
agama/inboundID/src/main/java/io/jans/inbound/Provider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package io.jans.inbound; | ||
|
||
public class Provider { | ||
|
||
private String flowQname; | ||
private String displayName; | ||
private String logoImg; | ||
private String mappingClassField; | ||
|
||
private boolean enabled = true; | ||
private boolean skipProfileUpdate; | ||
private boolean requestForEmail; | ||
private boolean emailLinkingSafe; | ||
|
||
public String getFlowQname() { | ||
return flowQname; | ||
} | ||
|
||
public void setFlowQname(String flowQname) { | ||
this.flowQname = flowQname; | ||
} | ||
|
||
public String getDisplayName() { | ||
return displayName; | ||
} | ||
|
||
public void setDisplayName(String displayName) { | ||
this.displayName = displayName; | ||
} | ||
|
||
public String getMappingClassField() { | ||
return mappingClassField; | ||
} | ||
|
||
public void setMappingClassField(String mappingClassField) { | ||
this.mappingClassField = mappingClassField; | ||
} | ||
|
||
public boolean isEnabled() { | ||
return enabled; | ||
} | ||
|
||
public void setEnabled(boolean enabled) { | ||
this.enabled = enabled; | ||
} | ||
|
||
public boolean isSkipProfileUpdate() { | ||
return skipProfileUpdate; | ||
} | ||
|
||
public void setSkipProfileUpdate(boolean skipProfileUpdate) { | ||
this.skipProfileUpdate = skipProfileUpdate; | ||
} | ||
|
||
public String getLogoImg() { | ||
return logoImg; | ||
} | ||
|
||
public void setLogoImg(String logoImg) { | ||
this.logoImg = logoImg; | ||
} | ||
|
||
public boolean isRequestForEmail() { | ||
return requestForEmail; | ||
} | ||
|
||
public void setRequestForEmail(boolean requestForEmail) { | ||
this.requestForEmail = requestForEmail; | ||
} | ||
|
||
public boolean isEmailLinkingSafe() { | ||
return emailLinkingSafe; | ||
} | ||
|
||
public void setEmailLinkingSafe(boolean emailLinkingSafe) { | ||
this.emailLinkingSafe = emailLinkingSafe; | ||
} | ||
|
||
} |
Oops, something went wrong.