]>
git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.util/src/org/argeo/osgi/useradmin/UserAdminConf.java
1 package org
.argeo
.osgi
.useradmin
;
3 import java
.net
.InetAddress
;
5 import java
.net
.URISyntaxException
;
6 import java
.net
.UnknownHostException
;
7 import java
.util
.Dictionary
;
8 import java
.util
.Hashtable
;
12 import javax
.naming
.Context
;
13 import javax
.naming
.InvalidNameException
;
14 import javax
.naming
.ldap
.LdapName
;
16 import org
.argeo
.util
.naming
.NamingUtils
;
18 /** Properties used to configure user admins. */
19 public enum UserAdminConf
{
20 /** Base DN (cannot be configured externally) */
21 baseDn("dc=example,dc=com"),
23 /** URI of the underlying resource (cannot be configured externally) */
24 uri("ldap://localhost:10389"),
26 /** User objectClass */
27 userObjectClass("inetOrgPerson"),
29 /** Relative base DN for users */
30 userBase("ou=People"),
32 /** Groups objectClass */
33 groupObjectClass("groupOfNames"),
35 /** Relative base DN for users */
36 groupBase("ou=Groups"),
38 /** Relative base DN for users */
39 systemRoleBase("ou=Roles"),
41 /** Read-only source */
44 /** Disabled source */
47 /** Authentication realm */
50 /** Override all passwords with this value (typically for testing purposes) */
53 public final static String FACTORY_PID
= "org.argeo.osgi.useradmin.config";
55 public final static String SCHEME_LDAP
= "ldap";
56 public final static String SCHEME_LDAPS
= "ldaps";
57 public final static String SCHEME_FILE
= "file";
58 public final static String SCHEME_OS
= "os";
59 public final static String SCHEME_IPA
= "ipa";
61 /** The default value. */
64 UserAdminConf(Object def
) {
68 public Object
getDefault() {
73 * For use as Java property.
75 * @deprecated use {@link #name()} instead
78 public String
property() {
82 public String
getValue(Dictionary
<String
, ?
> properties
) {
83 Object res
= getRawValue(properties
);
86 return res
.toString();
89 @SuppressWarnings("unchecked")
90 public <T
> T
getRawValue(Dictionary
<String
, ?
> properties
) {
91 Object res
= properties
.get(name());
97 /** @deprecated use {@link #valueOf(String)} instead */
99 public static UserAdminConf
local(String property
) {
100 return UserAdminConf
.valueOf(property
);
103 /** Hides host and credentials. */
104 public static URI
propertiesAsUri(Dictionary
<String
, ?
> properties
) {
105 StringBuilder query
= new StringBuilder();
107 boolean first
= true;
108 // for (Enumeration<String> keys = properties.keys(); keys.hasMoreElements();) {
109 // String key = keys.nextElement();
110 // // TODO clarify which keys are relevant (list only the enum?)
111 // if (!key.equals("service.factoryPid") && !key.equals("cn") && !key.equals("dn")
112 // && !key.equals(Constants.SERVICE_PID) && !key.startsWith("java") && !key.equals(baseDn.name())
113 // && !key.equals(uri.name()) && !key.equals(Constants.OBJECTCLASS)
114 // && !key.equals(Constants.SERVICE_ID) && !key.equals("bundle.id")) {
118 // query.append('&');
119 // query.append(valueOf(key).name());
120 // query.append('=').append(properties.get(key).toString());
124 keys
: for (UserAdminConf key
: UserAdminConf
.values()) {
125 if (key
.equals(baseDn
) || key
.equals(uri
))
127 Object value
= properties
.get(key
.name());
134 query
.append(key
.name());
135 query
.append('=').append(value
.toString());
139 Object bDnObj
= properties
.get(baseDn
.name());
140 String bDn
= bDnObj
!= null ? bDnObj
.toString() : null;
142 return new URI(null, null, bDn
!= null ?
'/' + bDn
: null, query
.length() != 0 ? query
.toString() : null,
144 } catch (URISyntaxException e
) {
145 throw new IllegalArgumentException("Cannot create URI from properties", e
);
149 public static Dictionary
<String
, Object
> uriAsProperties(String uriStr
) {
151 Hashtable
<String
, Object
> res
= new Hashtable
<String
, Object
>();
152 URI u
= new URI(uriStr
);
153 String scheme
= u
.getScheme();
154 if (scheme
!= null && scheme
.equals(SCHEME_IPA
)) {
155 return IpaUtils
.convertIpaUri(u
);
156 // scheme = u.getScheme();
158 String path
= u
.getPath();
160 String bDn
= path
.substring(path
.lastIndexOf('/') + 1, path
.length());
161 if (bDn
.equals("") && SCHEME_OS
.equals(scheme
)) {
162 bDn
= getBaseDnFromHostname();
165 if (bDn
.endsWith(".ldif"))
166 bDn
= bDn
.substring(0, bDn
.length() - ".ldif".length());
168 // Normalize base DN as LDAP name
169 bDn
= new LdapName(bDn
).toString();
171 String principal
= null;
172 String credentials
= null;
174 if (scheme
.equals(SCHEME_LDAP
) || scheme
.equals(SCHEME_LDAPS
)) {
175 // TODO additional checks
176 if (u
.getUserInfo() != null) {
177 String
[] userInfo
= u
.getUserInfo().split(":");
178 principal
= userInfo
.length
> 0 ? userInfo
[0] : null;
179 credentials
= userInfo
.length
> 1 ? userInfo
[1] : null;
181 } else if (scheme
.equals(SCHEME_FILE
)) {
182 } else if (scheme
.equals(SCHEME_IPA
)) {
183 } else if (scheme
.equals(SCHEME_OS
)) {
185 throw new IllegalArgumentException("Unsupported scheme " + scheme
);
186 Map
<String
, List
<String
>> query
= NamingUtils
.queryToMap(u
);
187 for (String key
: query
.keySet()) {
188 UserAdminConf ldapProp
= UserAdminConf
.valueOf(key
);
189 List
<String
> values
= query
.get(key
);
190 if (values
.size() == 1) {
191 res
.put(ldapProp
.name(), values
.get(0));
193 throw new IllegalArgumentException("Only single values are supported");
196 res
.put(baseDn
.name(), bDn
);
197 if (SCHEME_OS
.equals(scheme
))
198 res
.put(readOnly
.name(), "true");
199 if (principal
!= null)
200 res
.put(Context
.SECURITY_PRINCIPAL
, principal
);
201 if (credentials
!= null)
202 res
.put(Context
.SECURITY_CREDENTIALS
, credentials
);
203 if (scheme
!= null) {// relative URIs are dealt with externally
204 if (SCHEME_OS
.equals(scheme
)) {
205 res
.put(uri
.name(), SCHEME_OS
+ ":///");
207 URI bareUri
= new URI(scheme
, null, u
.getHost(), u
.getPort(),
208 scheme
.equals(SCHEME_FILE
) ? u
.getPath() : null, null, null);
209 res
.put(uri
.name(), bareUri
.toString());
213 } catch (URISyntaxException
| InvalidNameException e
) {
214 throw new IllegalArgumentException("Cannot convert " + uri
+ " to properties", e
);
218 private static String
getBaseDnFromHostname() {
221 hostname
= InetAddress
.getLocalHost().getHostName();
222 } catch (UnknownHostException e
) {
223 hostname
= "localhost.localdomain";
225 int dotIdx
= hostname
.indexOf('.');
227 String domain
= hostname
.substring(dotIdx
+ 1, hostname
.length());
228 String bDn
= ("." + domain
).replaceAll("\\.", ",dc=");
229 bDn
= bDn
.substring(1, bDn
.length());
232 return "dc=" + hostname
;
237 * Hash the base DN in order to have a deterministic string to be used as a cn
238 * for the underlying user directory.
240 public static String
baseDnHash(Dictionary
<String
, Object
> properties
) {
241 String bDn
= (String
) properties
.get(baseDn
.name());
243 throw new IllegalStateException("No baseDn in " + properties
);
244 return DigestUtils
.sha1str(bDn
);