]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.security.core/src/org/argeo/util/naming/LdifParser.java
Use deploy config for node user admin
[lgpl/argeo-commons.git] / org.argeo.security.core / src / org / argeo / util / naming / LdifParser.java
1 package org.argeo.util.naming;
2
3 import static org.argeo.osgi.useradmin.LdifName.dn;
4
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.util.List;
8 import java.util.SortedMap;
9 import java.util.TreeMap;
10
11 import javax.naming.InvalidNameException;
12 import javax.naming.NamingException;
13 import javax.naming.directory.Attribute;
14 import javax.naming.directory.Attributes;
15 import javax.naming.directory.BasicAttribute;
16 import javax.naming.directory.BasicAttributes;
17 import javax.naming.ldap.LdapName;
18 import javax.naming.ldap.Rdn;
19
20 import org.apache.commons.codec.binary.Base64;
21 import org.apache.commons.io.IOUtils;
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.argeo.osgi.useradmin.UserDirectoryException;
25
26 /** Basic LDIF parser. */
27 public class LdifParser {
28 private final static Log log = LogFactory.getLog(LdifParser.class);
29
30 protected Attributes addAttributes(SortedMap<LdapName, Attributes> res, int lineNumber, LdapName currentDn,
31 Attributes currentAttributes) {
32 try {
33 Rdn nameRdn = currentDn.getRdn(currentDn.size() - 1);
34 Attribute nameAttr = currentAttributes.get(nameRdn.getType());
35 if (nameAttr == null)
36 currentAttributes.put(nameRdn.getType(), nameRdn.getValue());
37 else if (!nameAttr.get().equals(nameRdn.getValue()))
38 throw new UserDirectoryException(
39 "Attribute " + nameAttr.getID() + "=" + nameAttr.get() + " not consistent with DN " + currentDn
40 + " (shortly before line " + lineNumber + " in LDIF file)");
41 Attributes previous = res.put(currentDn, currentAttributes);
42 if (log.isTraceEnabled())
43 log.trace("Added " + currentDn);
44 return previous;
45 } catch (NamingException e) {
46 throw new UserDirectoryException("Cannot add " + currentDn, e);
47 }
48 }
49
50 public SortedMap<LdapName, Attributes> read(InputStream in) throws IOException {
51 SortedMap<LdapName, Attributes> res = new TreeMap<LdapName, Attributes>();
52 try {
53 List<String> lines = IOUtils.readLines(in);
54 if (lines.size() == 0)
55 return res;
56 // add an empty new line since the last line is not checked
57 if (!lines.get(lines.size() - 1).equals(""))
58 lines.add("");
59
60 LdapName currentDn = null;
61 Attributes currentAttributes = null;
62 StringBuilder currentEntry = new StringBuilder();
63
64 readLines: for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) {
65 String line = lines.get(lineNumber);
66 boolean isLastLine = false;
67 if (lineNumber == lines.size() - 1)
68 isLastLine = true;
69 if (line.startsWith(" ")) {
70 currentEntry.append(line.substring(1));
71 if (!isLastLine)
72 continue readLines;
73 }
74
75 if (currentEntry.length() != 0 || isLastLine) {
76 // read previous attribute
77 StringBuilder attrId = new StringBuilder(8);
78 boolean isBase64 = false;
79 readAttrId: for (int i = 0; i < currentEntry.length(); i++) {
80 char c = currentEntry.charAt(i);
81 if (c == ':') {
82 if (i + 1 < currentEntry.length() && currentEntry.charAt(i + 1) == ':')
83 isBase64 = true;
84 currentEntry.delete(0, i + (isBase64 ? 2 : 1));
85 break readAttrId;
86 } else {
87 attrId.append(c);
88 }
89 }
90
91 String attributeId = attrId.toString();
92 String cleanValueStr = currentEntry.toString().trim();
93 Object attributeValue = isBase64 ? Base64.decodeBase64(cleanValueStr) : cleanValueStr;
94
95 // manage DN attributes
96 if (attributeId.equals(dn.name()) || isLastLine) {
97 if (currentDn != null) {
98 //
99 // ADD
100 //
101 Attributes previous = addAttributes(res, lineNumber, currentDn, currentAttributes);
102 if (previous != null) {
103 log.warn("There was already an entry with DN " + currentDn
104 + ", which has been discarded by a subsequent one.");
105 }
106 }
107
108 if (attributeId.equals(dn.name()))
109 try {
110 currentDn = new LdapName(attributeValue.toString());
111 currentAttributes = new BasicAttributes(true);
112 } catch (InvalidNameException e) {
113 log.error(attributeValue + " not a valid DN, skipping the entry.");
114 currentDn = null;
115 currentAttributes = null;
116 }
117 }
118
119 // store attribute
120 if (currentAttributes != null) {
121 Attribute attribute = currentAttributes.get(attributeId);
122 if (attribute == null) {
123 attribute = new BasicAttribute(attributeId);
124 currentAttributes.put(attribute);
125 }
126 attribute.add(attributeValue);
127 }
128 currentEntry = new StringBuilder();
129 }
130 currentEntry.append(line);
131 }
132 } finally {
133 IOUtils.closeQuietly(in);
134 }
135 return res;
136 }
137 }