]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.enterprise/src/org/argeo/osgi/useradmin/UserAdminConf.java
Factorize 'node' URI scheme constant.
[lgpl/argeo-commons.git] / org.argeo.enterprise / src / org / argeo / osgi / useradmin / UserAdminConf.java
1 package org.argeo.osgi.useradmin;
2
3 import java.io.UnsupportedEncodingException;
4 import java.net.URI;
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;
13 import java.util.Map;
14
15 import javax.naming.Context;
16
17 import org.osgi.framework.Constants;
18
19 /** Properties used to configure user admins. */
20 public enum UserAdminConf {
21 /** Base DN (cannot be configured externally) */
22 baseDn("dc=example,dc=com"),
23
24 /** URI of the underlying resource (cannot be configured externally) */
25 uri("ldap://localhost:10389"),
26
27 /** User objectClass */
28 userObjectClass("inetOrgPerson"),
29
30 /** Relative base DN for users */
31 userBase("ou=People"),
32
33 /** Groups objectClass */
34 groupObjectClass("groupOfNames"),
35
36 /** Relative base DN for users */
37 groupBase("ou=Groups"),
38
39 /** Read-only source */
40 readOnly(null);
41
42 public final static String FACTORY_PID = "org.argeo.osgi.useradmin.config";
43
44 /** The default value. */
45 private Object def;
46
47 UserAdminConf(Object def) {
48 this.def = def;
49 }
50
51 public Object getDefault() {
52 return def;
53 }
54
55 /**
56 * For use as Java property.
57 *
58 * @deprecated use {@link #name()} instead
59 */
60 @Deprecated
61 public String property() {
62 return name();
63 }
64
65 public String getValue(Dictionary<String, ?> properties) {
66 Object res = getRawValue(properties);
67 if (res == null)
68 return null;
69 return res.toString();
70 }
71
72 @SuppressWarnings("unchecked")
73 public <T> T getRawValue(Dictionary<String, ?> properties) {
74 Object res = properties.get(name());
75 if (res == null)
76 res = getDefault();
77 return (T) res;
78 }
79
80 /** @deprecated use {@link #valueOf(String)} instead */
81 @Deprecated
82 public static UserAdminConf local(String property) {
83 return UserAdminConf.valueOf(property);
84 }
85
86 /** Hides host and credentials. */
87 public static URI propertiesAsUri(Dictionary<String, ?> properties) {
88 StringBuilder query = new StringBuilder();
89
90 boolean first = true;
91 for (Enumeration<String> keys = properties.keys(); keys.hasMoreElements();) {
92 String key = keys.nextElement();
93 // TODO clarify which keys are relevant (list only the enum?)
94 if (!key.equals("service.factoryPid") && !key.equals("cn") && !key.equals("dn")
95 && !key.equals(Constants.SERVICE_PID) && !key.startsWith("java") && !key.equals(baseDn.name())
96 && !key.equals(uri.name())) {
97 if (first)
98 first = false;
99 else
100 query.append('&');
101 query.append(valueOf(key).name());
102 query.append('=').append(properties.get(key).toString());
103 }
104 }
105
106 String bDn = (String) properties.get(baseDn.name());
107 try {
108 return new URI(null, null, bDn != null ? '/' + bDn : null, query.length() != 0 ? query.toString() : null,
109 null);
110 } catch (URISyntaxException e) {
111 throw new UserDirectoryException("Cannot create URI from properties", e);
112 }
113 }
114
115 public static Dictionary<String, Object> uriAsProperties(String uriStr) {
116 try {
117 Hashtable<String, Object> res = new Hashtable<String, Object>();
118 URI u = new URI(uriStr);
119 String scheme = u.getScheme();
120 String path = u.getPath();
121 String bDn = path.substring(path.lastIndexOf('/') + 1, path.length());
122 if (bDn.endsWith(".ldif"))
123 bDn = bDn.substring(0, bDn.length() - ".ldif".length());
124
125 String principal = null;
126 String credentials = null;
127 if (scheme != null)
128 if (scheme.equals("ldap") || scheme.equals("ldaps")) {
129 // TODO additional checks
130 if (u.getUserInfo() != null) {
131 String[] userInfo = u.getUserInfo().split(":");
132 principal = userInfo.length > 0 ? userInfo[0] : null;
133 credentials = userInfo.length > 1 ? userInfo[1] : null;
134 }
135 } else if (scheme.equals("file")) {
136 } else
137 throw new UserDirectoryException("Unsupported scheme " + scheme);
138 Map<String, List<String>> query = splitQuery(u.getQuery());
139 for (String key : query.keySet()) {
140 UserAdminConf ldapProp = UserAdminConf.valueOf(key);
141 List<String> values = query.get(key);
142 if (values.size() == 1) {
143 res.put(ldapProp.name(), values.get(0));
144 } else {
145 throw new UserDirectoryException("Only single values are supported");
146 }
147 }
148 res.put(baseDn.name(), bDn);
149 if (principal != null)
150 res.put(Context.SECURITY_PRINCIPAL, principal);
151 if (credentials != null)
152 res.put(Context.SECURITY_CREDENTIALS, credentials);
153 if (scheme != null) {
154 URI bareUri = new URI(scheme, null, u.getHost(), u.getPort(),
155 scheme.equals("file") ? u.getPath() : null, null, null);
156 res.put(uri.name(), bareUri.toString());
157 }
158 return res;
159 } catch (Exception e) {
160 throw new UserDirectoryException("Cannot convert " + uri + " to properties", e);
161 }
162 }
163
164 private static Map<String, List<String>> splitQuery(String query) throws UnsupportedEncodingException {
165 final Map<String, List<String>> query_pairs = new LinkedHashMap<String, List<String>>();
166 if (query == null)
167 return query_pairs;
168 final String[] pairs = query.split("&");
169 for (String pair : pairs) {
170 final int idx = pair.indexOf("=");
171 final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;
172 if (!query_pairs.containsKey(key)) {
173 query_pairs.put(key, new LinkedList<String>());
174 }
175 final String value = idx > 0 && pair.length() > idx + 1
176 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null;
177 query_pairs.get(key).add(value);
178 }
179 return query_pairs;
180 }
181
182 public static void main(String[] args) {
183 Dictionary<String, ?> props = uriAsProperties("ldap://" + "uid=admin,ou=system:secret@localhost:10389"
184 + "/dc=example,dc=com" + "?readOnly=false&userObjectClass=person");
185 System.out.println(props);
186 System.out.println(propertiesAsUri(props));
187
188 System.out.println(uriAsProperties("file://some/dir/dc=example,dc=com.ldif"));
189
190 props = uriAsProperties(
191 "/dc=example,dc=com.ldif?readOnly=true" + "&userBase=ou=CoWorkers,ou=People&groupBase=ou=Roles");
192 System.out.println(props);
193 System.out.println(propertiesAsUri(props));
194 }
195 }