1 package org
.argeo
.osgi
.useradmin
;
3 import java
.io
.UnsupportedEncodingException
;
5 import java
.net
.URLDecoder
;
6 import java
.util
.Dictionary
;
7 import java
.util
.Hashtable
;
8 import java
.util
.LinkedHashMap
;
9 import java
.util
.LinkedList
;
10 import java
.util
.List
;
13 import javax
.naming
.Context
;
15 public enum LdapProperties
{
17 baseDn("dc=example,dc=com"),
19 /** URI of the underlying resource */
20 uri("ldap://localhost:10389"),
22 /** User objectClass */
23 userObjectClass("inetOrgPerson"),
25 /** Groups objectClass */
26 groupObjectClass("groupOfNames"),
28 /** Read-only source */
31 private static String PREFIX
= "argeo.ldap.";
33 /** The default value. */
36 LdapProperties(Object def
) {
40 public Object
getDefault() {
44 public String
getFullName() {
45 return getPrefix() + name();
48 public String
getPrefix() {
52 public String
getValue(Dictionary
<String
, ?
> properties
) {
53 Object res
= getRawValue(properties
);
56 return res
.toString();
59 @SuppressWarnings("unchecked")
60 public <T
> T
getRawValue(Dictionary
<String
, ?
> properties
) {
61 Object res
= properties
.get(getFullName());
67 public static Dictionary
<String
, ?
> uriAsProperties(String uriStr
) {
69 Hashtable
<String
, Object
> res
= new Hashtable
<String
, Object
>();
70 URI u
= new URI(uriStr
);
71 String scheme
= u
.getScheme();
72 String path
= u
.getPath();
73 String bDn
= path
.substring(path
.lastIndexOf('/') + 1,
75 String principal
= null;
76 String credentials
= null;
78 if (scheme
.equals("ldap") || scheme
.equals("ldaps")) {
79 // TODO additional checks
80 String
[] userInfo
= u
.getUserInfo().split(":");
81 principal
= userInfo
.length
> 0 ? userInfo
[0] : null;
82 credentials
= userInfo
.length
> 1 ? userInfo
[1] : null;
83 } else if (scheme
.equals("file")) {
84 if (bDn
.endsWith(".ldif")) {
85 bDn
= bDn
.substring(0, bDn
.length() - ".ldif".length());
88 throw new UserDirectoryException("Unsupported scheme "
90 Map
<String
, List
<String
>> query
= splitQuery(u
.getQuery());
91 for (String key
: query
.keySet()) {
92 LdapProperties ldapProp
= LdapProperties
.valueOf(key
);
93 List
<String
> values
= query
.get(key
);
94 if (values
.size() == 1) {
95 res
.put(ldapProp
.getFullName(), values
.get(0));
97 throw new UserDirectoryException(
98 "Only single values are supported");
101 res
.put(baseDn
.getFullName(), bDn
);
102 if (principal
!= null)
103 res
.put(Context
.SECURITY_PRINCIPAL
, principal
);
104 if (credentials
!= null)
105 res
.put(Context
.SECURITY_CREDENTIALS
, credentials
);
106 if (scheme
!= null) {
107 URI bareUri
= new URI(scheme
, null, u
.getHost(), u
.getPort(),
108 scheme
.equals("file") ? u
.getPath() : null, null, null);
109 res
.put(uri
.getFullName(), bareUri
.toString());
112 } catch (Exception e
) {
113 throw new UserDirectoryException("Cannot convert " + uri
114 + " to properties", e
);
118 public static Map
<String
, List
<String
>> splitQuery(String query
)
119 throws UnsupportedEncodingException
{
120 final Map
<String
, List
<String
>> query_pairs
= new LinkedHashMap
<String
, List
<String
>>();
123 final String
[] pairs
= query
.split("&");
124 for (String pair
: pairs
) {
125 final int idx
= pair
.indexOf("=");
126 final String key
= idx
> 0 ? URLDecoder
.decode(
127 pair
.substring(0, idx
), "UTF-8") : pair
;
128 if (!query_pairs
.containsKey(key
)) {
129 query_pairs
.put(key
, new LinkedList
<String
>());
131 final String value
= idx
> 0 && pair
.length() > idx
+ 1 ? URLDecoder
132 .decode(pair
.substring(idx
+ 1), "UTF-8") : null;
133 query_pairs
.get(key
).add(value
);
138 public static void main(String
[] args
) {
139 System
.out
.println(uriAsProperties("ldap://"
140 + "uid=admin,ou=system:secret@localhost:10389"
141 + "/dc=example,dc=com"
142 + "?readOnly=false&userObjectClass=person"));
144 .println(uriAsProperties("file://some/dir/dc=example,dc=com.ldif"));
146 .println(uriAsProperties("/dc=example,dc=com.ldif?readOnly=true"));