1 package org
.argeo
.osgi
.useradmin
;
3 import java
.io
.UnsupportedEncodingException
;
5 import java
.net
.URISyntaxException
;
6 import java
.net
.URLDecoder
;
7 import java
.util
.Dictionary
;
8 import java
.util
.Enumeration
;
9 import java
.util
.Hashtable
;
10 import java
.util
.LinkedHashMap
;
11 import java
.util
.LinkedList
;
12 import java
.util
.List
;
15 import javax
.naming
.Context
;
17 public enum UserAdminProps
{
19 baseDn("dc=example,dc=com"),
21 /** URI of the underlying resource */
22 uri("ldap://localhost:10389"),
24 /** User objectClass */
25 userObjectClass("inetOrgPerson"),
27 /** Relative base DN for users */
30 /** Groups objectClass */
31 groupObjectClass("groupOfNames"),
33 /** Relative base DN for users */
34 groupBase("ou=groups"),
36 /** Read-only source */
39 private static String PREFIX
= "argeo.useradmin";
41 /** The default value. */
44 UserAdminProps(Object def
) {
48 public Object
getDefault() {
52 public String
property() {
53 return getPrefix() + name();
56 public String
getPrefix() {
60 public String
getValue(Dictionary
<String
, ?
> properties
) {
61 Object res
= getRawValue(properties
);
64 return res
.toString();
67 @SuppressWarnings("unchecked")
68 public <T
> T
getRawValue(Dictionary
<String
, ?
> properties
) {
69 Object res
= properties
.get(property());
75 /** Hides host and credentials. */
76 public static URI
propertiesAsUri(Dictionary
<String
, ?
> properties
) {
77 StringBuilder query
= new StringBuilder();
80 for (Enumeration
<String
> keys
= properties
.keys(); keys
81 .hasMoreElements();) {
82 String key
= keys
.nextElement();
83 if (key
.startsWith(PREFIX
) && !key
.equals(baseDn
.property())
84 && !key
.equals(uri
.property())) {
89 query
.append(key
.substring(PREFIX
.length()));
90 query
.append('=').append(properties
.get(key
).toString());
94 String bDn
= (String
) properties
.get(baseDn
.property());
96 return new URI(null, null, bDn
!= null ?
'/' + bDn
: null,
97 query
.length() != 0 ? query
.toString() : null, null);
98 } catch (URISyntaxException e
) {
99 throw new UserDirectoryException(
100 "Cannot create URI from properties", e
);
104 public static Dictionary
<String
, ?
> uriAsProperties(String uriStr
) {
106 Hashtable
<String
, Object
> res
= new Hashtable
<String
, Object
>();
107 URI u
= new URI(uriStr
);
108 String scheme
= u
.getScheme();
109 String path
= u
.getPath();
110 String bDn
= path
.substring(path
.lastIndexOf('/') + 1,
112 if (bDn
.endsWith(".ldif"))
113 bDn
= bDn
.substring(0, bDn
.length() - ".ldif".length());
115 String principal
= null;
116 String credentials
= null;
118 if (scheme
.equals("ldap") || scheme
.equals("ldaps")) {
119 // TODO additional checks
120 String
[] userInfo
= u
.getUserInfo().split(":");
121 principal
= userInfo
.length
> 0 ? userInfo
[0] : null;
122 credentials
= userInfo
.length
> 1 ? userInfo
[1] : null;
123 } else if (scheme
.equals("file")) {
125 throw new UserDirectoryException("Unsupported scheme "
127 Map
<String
, List
<String
>> query
= splitQuery(u
.getQuery());
128 for (String key
: query
.keySet()) {
129 UserAdminProps ldapProp
= UserAdminProps
.valueOf(key
);
130 List
<String
> values
= query
.get(key
);
131 if (values
.size() == 1) {
132 res
.put(ldapProp
.property(), values
.get(0));
134 throw new UserDirectoryException(
135 "Only single values are supported");
138 res
.put(baseDn
.property(), bDn
);
139 if (principal
!= null)
140 res
.put(Context
.SECURITY_PRINCIPAL
, principal
);
141 if (credentials
!= null)
142 res
.put(Context
.SECURITY_CREDENTIALS
, credentials
);
143 if (scheme
!= null) {
144 URI bareUri
= new URI(scheme
, null, u
.getHost(), u
.getPort(),
145 scheme
.equals("file") ? u
.getPath() : null, null, null);
146 res
.put(uri
.property(), bareUri
.toString());
149 } catch (Exception e
) {
150 throw new UserDirectoryException("Cannot convert " + uri
151 + " to properties", e
);
155 private static Map
<String
, List
<String
>> splitQuery(String query
)
156 throws UnsupportedEncodingException
{
157 final Map
<String
, List
<String
>> query_pairs
= new LinkedHashMap
<String
, List
<String
>>();
160 final String
[] pairs
= query
.split("&");
161 for (String pair
: pairs
) {
162 final int idx
= pair
.indexOf("=");
163 final String key
= idx
> 0 ? URLDecoder
.decode(
164 pair
.substring(0, idx
), "UTF-8") : pair
;
165 if (!query_pairs
.containsKey(key
)) {
166 query_pairs
.put(key
, new LinkedList
<String
>());
168 final String value
= idx
> 0 && pair
.length() > idx
+ 1 ? URLDecoder
169 .decode(pair
.substring(idx
+ 1), "UTF-8") : null;
170 query_pairs
.get(key
).add(value
);
175 public static void main(String
[] args
) {
176 Dictionary
<String
, ?
> props
= uriAsProperties("ldap://"
177 + "uid=admin,ou=system:secret@localhost:10389"
178 + "/dc=example,dc=com"
179 + "?readOnly=false&userObjectClass=person");
180 System
.out
.println(props
);
181 System
.out
.println(propertiesAsUri(props
));
184 .println(uriAsProperties("file://some/dir/dc=example,dc=com.ldif"));
186 props
= uriAsProperties("/dc=example,dc=com.ldif?readOnly=true"
187 + "&userBase=ou=CoWorkers,ou=People&groupBase=ou=Roles");
188 System
.out
.println(props
);
189 System
.out
.println(propertiesAsUri(props
));