View Javadoc

1   /*
2    * Copyright (c) 2004 UNINETT FAS
3    *
4    * This program is free software; you can redistribute it and/or modify it
5    * under the terms of the GNU General Public License as published by the Free
6    * Software Foundation; either version 2 of the License, or (at your option)
7    * any later version.
8    *
9    * This program is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11   * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12   * more details.
13   *
14   * You should have received a copy of the GNU General Public License along with
15   * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16   * Place - Suite 330, Boston, MA 02111-1307, USA.
17   *
18   */
19  
20  package no.feide.moria.directory.backend;
21  
22  import java.util.ArrayList;
23  import java.util.HashMap;
24  import java.util.Iterator;
25  
26  import no.feide.moria.directory.Credentials;
27  import no.feide.moria.directory.DirectoryManagerConfigurationException;
28  import no.feide.moria.directory.index.IndexedReference;
29  
30  import org.jdom.Element;
31  
32  /***
33   * Hard-coded dummy backend, for testing. Does not require an actual backend
34   * source.
35   */
36  public class DummyBackend
37  implements DirectoryManagerBackend {
38  
39      /***
40       * Maps user names (converted to lowercase) to <code>DummyUser</code>
41       * elements.
42       */
43      private HashMap users;
44  
45  
46      /***
47       * Protected constructor. Sets the configuration used by this instance.
48       * @param config
49       *            A <code>Backend</code> configuration element. Must contain a
50       *            <code>Dummy</code> element (if more than one only the first
51       *            is considered), which is expected to contain one or more
52       *            <code>User</code> elements, each with one or more
53       *            <code>Attribute</code> elements, which again have
54       *            <code>Value</code> elements with exactly one value child.
55       *            Allows for easy configuration of test cases, without having to
56       *            rely on an external backend source. See the supplied dummy
57       *            configuration for a workable example. Note that attribute and
58       *            user names are case insensitive, while attribute values are
59       *            stored as specified in the configuration.
60       * @throws DirectoryManagerConfigurationException
61       *             If config lacks a mandatory element.
62       */
63      protected DummyBackend(final Element config) {
64  
65          // Get Dummy element, with sanity check.
66          final Element dummy = config.getChild("Dummy");
67          if (dummy == null)
68              throw new DirectoryManagerConfigurationException("Missing Dummy element");
69  
70          // Parse any user elements.
71          users = new HashMap();
72          if (dummy.getChildren("User") == null)
73              throw new DirectoryManagerConfigurationException("Missing User element(s)");
74          final Iterator userElements = dummy.getChildren("User").iterator();
75          while (userElements.hasNext()) {
76  
77              // Parse any attribute elements.
78              HashMap attributes = new HashMap();
79              final Element user = (Element) userElements.next();
80              final Iterator attributeElements = user.getChildren("Attribute").iterator();
81              while (attributeElements.hasNext()) {
82  
83                  // Parse any value elements.
84                  ArrayList values = new ArrayList();
85                  final Element attribute = (Element) attributeElements.next();
86                  final Iterator valueElements = attribute.getChildren("Value").iterator();
87                  while (valueElements.hasNext()) {
88  
89                      // Parse the attribute values.
90                      final Element value = (Element) valueElements.next();
91                      values.add(value.getText());
92  
93                  }
94  
95                  // Map an attribute to its values.
96                  attributes.put(attribute.getAttributeValue("name").toLowerCase(), values);
97  
98              }
99  
100             // Add a new user.
101             DummyUser newUser = new DummyUser(user.getAttributeValue("name"), user.getAttributeValue("password"), attributes);
102             users.put(user.getAttributeValue("name").toLowerCase(), newUser);
103 
104         }
105 
106     }
107 
108 
109     /***
110      * Does nothing, but needed to fulfill the
111      * <code>DirectoryManagerBackend</code> interface.
112      * @param references
113      *            Ignored.
114      * @see DirectoryManagerBackend#open(IndexedReference[])
115      */
116     public void open(final IndexedReference[] references) {
117 
118         // Does nothing.
119 
120     }
121 
122 
123     /***
124      * Checks whether a user exists.
125      * @param username
126      *            The username. Case is ignored.
127      * @return true if the user exists, false otherwise.
128      * @see DirectoryManagerBackend#userExists(String)
129      */
130     public final boolean userExists(final String username) {
131 
132         if (username == null)
133             return false;
134         return users.containsKey(username.toLowerCase());
135 
136     }
137 
138 
139     /***
140      * Authenticates a user, if the user exists and the username equals the
141      * password.
142      * @param userCredentials
143      *            The user's credentials. Cannot be <code>null</code>.
144      * @param attributeRequest
145      *            A list of requested attributes from the user object. May be
146      *            <code>null</code> or an empty array. Not case sensitive.
147      * @return User attributes, possibly empty.
148      * @throws AuthenticationFailedException
149      *             If the authentication fails.
150      * @throws IllegalArgumentException
151      *             If userCredentials are <code>null</code>.
152      * @see DirectoryManagerBackend#authenticate(Credentials, String[])
153      */
154     public final HashMap authenticate(final Credentials userCredentials,
155                                       final String[] attributeRequest) throws AuthenticationFailedException {
156 
157         // Sanity check.
158         if (userCredentials == null)
159             throw new IllegalArgumentException("Credentials cannot be NULL");
160 
161         // Find and authenticate user.
162         DummyUser user = (DummyUser) users.get(userCredentials.getUsername());
163         if ((user != null) && (user.authenticate(userCredentials.getUsername(), userCredentials.getPassword()))) {
164 
165             // Successful authentication; return any requested user attributes.
166             return user.getAttributes(attributeRequest);
167 
168         }
169 
170         // Bad authentication.
171         throw new AuthenticationFailedException("User \"" + userCredentials.getUsername() + "\" failed authentication");
172 
173     }
174 
175 
176     /***
177      * Does nothing, but needed to fulfill the
178      * <code>DirectoryManagerBackend</code> interface.
179      * @see DirectoryManagerBackend#close()
180      */
181     public void close() {
182 
183         // Does nothing.
184 
185     }
186 
187 }