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