-
Notifications
You must be signed in to change notification settings - Fork 136
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
gplazma: Added a new map plugin with support for
- mapping OpenID Subject and Email Address to Username, Uid, Gid - mapping a principal to multiple principals (dn -> uid, gid, username) Parses a map file, which stores the maps between openid (subject) and the user. Additionally, it can also be used to map principals like DN (GlobusPrincipal) to Email (EmailAddress), Kerberos (KerberosPrincipal), Username, Uid and Gid etc (see example config). A sample mapping can look like 1. "dn:/C=DE/O=Hamburg/OU=desy.de/CN=Kermit The Frog" username:kermit 2. oidc:googleoidcsubject gid:1000,true uid:1000 3. "dn:/C=DE/O=Hamburg/OU=desy.de/CN=Kermit The Frog" uid:1000 4. "dn:/C=DE/O=Hamburg/OU=desy.de/CN=Kermit The Frog" uid:1000 gid:500, true gid:100 Currently, only "dn, oidc, username, uid, gid, kerberos, email" supported Ticket: Acked-by: Paul Millar <paul.millar@desy.de> Target: trunk Require-book: no Require-notes: no Patch: https://rb.dcache.org/r/9256
- Loading branch information
Showing
10 changed files
with
865 additions
and
0 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,39 @@ | ||
<?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> | ||
|
||
<parent> | ||
<groupId>org.dcache</groupId> | ||
<artifactId>dcache-parent</artifactId> | ||
<version>2.16.0-SNAPSHOT</version> | ||
<relativePath>../../pom.xml</relativePath> | ||
</parent> | ||
|
||
<artifactId>gplazma2-multimap</artifactId> | ||
<packaging>jar</packaging> | ||
|
||
<name>gPlazma 2 Multi Mapping Plugin</name> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>slf4j-api</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.google.guava</groupId> | ||
<artifactId>guava</artifactId> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.dcache</groupId> | ||
<artifactId>dcache-common</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.dcache</groupId> | ||
<artifactId>gplazma2</artifactId> | ||
<version>${project.version}</version> | ||
</dependency> | ||
</dependencies> | ||
</project> |
184 changes: 184 additions & 0 deletions
184
modules/gplazma2-multimap/src/main/java/org/dcache/gplazma/plugins/GplazmaMultiMapFile.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,184 @@ | ||
package org.dcache.gplazma.plugins; | ||
|
||
import org.globus.gsi.gssapi.jaas.GlobusPrincipal; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import javax.security.auth.kerberos.KerberosPrincipal; | ||
|
||
import java.io.BufferedReader; | ||
import java.io.File; | ||
import java.io.FileReader; | ||
import java.io.IOException; | ||
import java.security.Principal; | ||
import java.util.Collections; | ||
import java.util.HashMap; | ||
import java.util.Iterator; | ||
import java.util.LinkedHashSet; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Set; | ||
|
||
import org.dcache.auth.EmailAddressPrincipal; | ||
import org.dcache.auth.GidPrincipal; | ||
import org.dcache.auth.OidcSubjectPrincipal; | ||
import org.dcache.auth.UidPrincipal; | ||
import org.dcache.auth.UserNamePrincipal; | ||
import org.dcache.gplazma.AuthenticationException; | ||
import org.dcache.gplazma.plugins.exceptions.GplazmaParseMapFileException; | ||
import org.dcache.util.Args; | ||
|
||
public class GplazmaMultiMapFile | ||
{ | ||
private static final Logger LOG = LoggerFactory.getLogger(GplazmaMultiMapFile.class); | ||
|
||
private File file; | ||
private long lastLoaded; | ||
private Map<Principal,Set<Principal>> map = Collections.emptyMap(); | ||
private static final String[] principalTypes = new String[]{"dn", | ||
"email", | ||
"username", | ||
"kerberos", | ||
"oidc", | ||
"uid", | ||
"gid" }; | ||
|
||
public GplazmaMultiMapFile(String path) | ||
{ | ||
this(new File(path)); | ||
} | ||
|
||
public GplazmaMultiMapFile(File file) | ||
{ | ||
this.file = file; | ||
} | ||
|
||
public synchronized void ensureUpToDate() throws AuthenticationException | ||
{ | ||
if (lastLoaded <= file.lastModified()) { | ||
LOG.debug("Reading file {}", file); | ||
try { | ||
BufferedReader reader = new BufferedReader(new FileReader(file)); | ||
map = parseMapFile(reader); | ||
lastLoaded = System.currentTimeMillis(); | ||
} catch (IOException e) { | ||
throw new AuthenticationException( | ||
String.format("failed to read %s: %s", file.getName(), e.getMessage())); | ||
} | ||
} | ||
} | ||
|
||
private static Map<Principal,Set<Principal>> parseMapFile(BufferedReader reader) throws IOException | ||
{ | ||
Map<Principal,Set<Principal>> map = new HashMap<>(); | ||
String line; | ||
String lineOrig; | ||
int lineCount = 0; | ||
|
||
while ((line = reader.readLine()) != null) { | ||
lineOrig = line = line.trim(); | ||
lineCount++; | ||
if (line.isEmpty() || line.charAt(0) == '#') continue; | ||
|
||
try { | ||
List<Principal> principals = parse(line); | ||
|
||
if (!principals.isEmpty()) { | ||
Iterator<Principal> iterator = principals.iterator(); | ||
Set<Principal> mapSet = new LinkedHashSet<>(); | ||
|
||
Principal key = iterator.next(); | ||
while (iterator.hasNext()) { | ||
mapSet.add(iterator.next()); | ||
} | ||
|
||
if (!mapSet.isEmpty()) { | ||
if (!map.containsKey(key)) { | ||
map.put(key, mapSet); | ||
} else { | ||
LOG.warn("{}: Ignored Additional Mapping for key {}", | ||
lineCount, lineOrig, key); | ||
} | ||
} else { | ||
LOG.warn("{}: Empty Map", lineCount, lineOrig); | ||
} | ||
} | ||
} catch (GplazmaParseMapFileException e) { | ||
LOG.warn("{}: {}", lineCount, e.getMessage()); | ||
} | ||
} | ||
return map; | ||
} | ||
|
||
private static Principal createPrincipal(String predicate, String principal) throws GplazmaParseMapFileException { | ||
try { | ||
switch (predicate) { | ||
case "oidc": | ||
return new OidcSubjectPrincipal(principal); | ||
case "email": | ||
return new EmailAddressPrincipal(principal); | ||
case "username": | ||
return new UserNamePrincipal(principal); | ||
case "dn": | ||
return new GlobusPrincipal(principal); | ||
case "kerberos": | ||
return new KerberosPrincipal(principal); | ||
case "uid": | ||
return new UidPrincipal(principal); | ||
case "gid": | ||
return createGidPrincipal(principal); | ||
default: | ||
throw new GplazmaParseMapFileException("Not supported predicate [" + predicate + "]"); | ||
} | ||
} catch (IllegalArgumentException e) { | ||
throw new GplazmaParseMapFileException("Illegal Value [" + | ||
principal + | ||
"] to predicate [" + | ||
predicate + | ||
"]"); | ||
} | ||
|
||
} | ||
|
||
private static Principal createGidPrincipal(String principal) throws GplazmaParseMapFileException | ||
{ | ||
if (countNumCommas(principal) > 1) { | ||
throw new GplazmaParseMapFileException("Illegal Value [" + principal +"] for gid"); | ||
} else { | ||
String[] splits = principal.split(","); | ||
if (splits.length == 2) { | ||
return new GidPrincipal(splits[0], Boolean.parseBoolean(splits[1])); | ||
} else { | ||
return new GidPrincipal(principal, false); | ||
} | ||
} | ||
} | ||
|
||
private static List<Principal> parse(CharSequence line) throws GplazmaParseMapFileException | ||
{ | ||
final List<Principal> principals = new LinkedList<>(); | ||
Args args = new Args(line); | ||
for (int i = 0; i < args.argc(); i++) { | ||
String argument = args.argv(i); | ||
int colon = argument.indexOf(':'); | ||
if (colon != -1) { | ||
principals.add(createPrincipal(argument.substring(0, colon), | ||
argument.substring(colon + 1, argument.length()))); | ||
} else { | ||
throw new GplazmaParseMapFileException("Missing colon in \"" + argument+"\""); | ||
} | ||
} | ||
return principals; | ||
} | ||
|
||
private static int countNumCommas(String principal) { | ||
return principal.length() - principal.replace(",", "").length(); | ||
} | ||
|
||
public synchronized Set<Principal> getMappedPrincipals(Principal principal) | ||
{ | ||
Set<Principal> out = map.get(principal); | ||
return (out == null) ? Collections.emptySet(): out; | ||
} | ||
} |
41 changes: 41 additions & 0 deletions
41
...les/gplazma2-multimap/src/main/java/org/dcache/gplazma/plugins/GplazmaMultiMapPlugin.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,41 @@ | ||
package org.dcache.gplazma.plugins; | ||
|
||
import org.dcache.gplazma.AuthenticationException; | ||
import java.security.Principal; | ||
import java.util.Properties; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
|
||
import static com.google.common.base.Preconditions.checkArgument; | ||
import static com.google.common.base.Preconditions.checkNotNull; | ||
import static org.dcache.gplazma.util.Preconditions.checkAuthentication; | ||
|
||
public class GplazmaMultiMapPlugin implements GPlazmaMappingPlugin | ||
{ | ||
private GplazmaMultiMapFile mapFile; | ||
private static final String GPLAZMA2_MAP_FILE = "gplazma.multimapper.file"; | ||
|
||
public GplazmaMultiMapPlugin(Properties properties) | ||
{ | ||
String path = properties.getProperty(GPLAZMA2_MAP_FILE); | ||
checkArgument(path != null && !path.isEmpty(), "Undefined property: " + GPLAZMA2_MAP_FILE); | ||
mapFile = new GplazmaMultiMapFile(path); | ||
} | ||
|
||
public GplazmaMultiMapPlugin(GplazmaMultiMapFile mapFile) | ||
{ | ||
this.mapFile = checkNotNull(mapFile, "Multi-mapfile can't be null"); | ||
} | ||
|
||
@Override | ||
public void map(Set<Principal> principals) throws AuthenticationException | ||
{ | ||
mapFile.ensureUpToDate(); | ||
Set<Principal> mappedPrincipals = principals.stream() | ||
.flatMap(p -> mapFile.getMappedPrincipals(p).stream()) | ||
.collect(Collectors.toSet()); | ||
|
||
checkAuthentication(!mappedPrincipals.isEmpty(), "no mappable principals"); | ||
principals.addAll(mappedPrincipals); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
...map/src/main/java/org/dcache/gplazma/plugins/exceptions/GplazmaParseMapFileException.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,20 @@ | ||
package org.dcache.gplazma.plugins.exceptions; | ||
|
||
public class GplazmaParseMapFileException extends Exception { | ||
|
||
public GplazmaParseMapFileException() { | ||
super(); | ||
} | ||
|
||
public GplazmaParseMapFileException(String message) { | ||
super(message); | ||
} | ||
|
||
public GplazmaParseMapFileException(Throwable cause) { | ||
super(cause); | ||
} | ||
|
||
public GplazmaParseMapFileException(String message, Throwable cause) { | ||
super(message, cause); | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
modules/gplazma2-multimap/src/main/resources/META-INF/gplazma-plugins.xml
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,6 @@ | ||
<plugins> | ||
<plugin> | ||
<name>multimap</name> | ||
<class>org.dcache.gplazma.plugins.GplazmaMultiMapPlugin</class> | ||
</plugin> | ||
</plugins> |
Oops, something went wrong.