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