001: /**
002: *
003: */package org.acegisecurity.config;
004:
005: import java.util.ArrayList;
006: import java.util.HashMap;
007: import java.util.List;
008: import java.util.Map;
009: import java.util.Properties;
010:
011: import org.acegisecurity.GrantedAuthority;
012: import org.acegisecurity.GrantedAuthorityImpl;
013: import org.acegisecurity.userdetails.User;
014: import org.acegisecurity.userdetails.UserDetails;
015: import org.acegisecurity.userdetails.jdbc.JdbcDaoImpl;
016: import org.acegisecurity.userdetails.memory.InMemoryDaoImpl;
017: import org.acegisecurity.userdetails.memory.UserAttribute;
018: import org.acegisecurity.userdetails.memory.UserMap;
019: import org.apache.commons.logging.Log;
020: import org.apache.commons.logging.LogFactory;
021: import org.springframework.beans.factory.config.PropertiesFactoryBean;
022: import org.springframework.beans.factory.config.RuntimeBeanReference;
023: import org.springframework.beans.factory.support.AbstractBeanDefinition;
024: import org.springframework.beans.factory.support.BeanDefinitionBuilder;
025: import org.springframework.beans.factory.support.ManagedList;
026: import org.springframework.beans.factory.support.RootBeanDefinition;
027: import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
028: import org.springframework.beans.factory.xml.BeanDefinitionParser;
029: import org.springframework.beans.factory.xml.ParserContext;
030: import org.springframework.util.StringUtils;
031: import org.w3c.dom.Element;
032: import org.w3c.dom.Node;
033: import org.w3c.dom.NodeList;
034:
035: /**
036: * @author vpuri
037: *
038: */
039: public class PrincipalRepositoryBeanDefinitionParser extends
040: AbstractBeanDefinitionParser implements BeanDefinitionParser {
041:
042: // ~ Static fields/initializers
043: // =====================================================================================
044:
045: private static final Log logger = LogFactory
046: .getLog(PrincipalRepositoryBeanDefinitionParser.class);
047:
048: // ~ Instance fields
049: // ================================================================================================
050: private static final String JDBC = "jdbc";
051:
052: private static final String DATASOURCE_REF = "dataSourceBeanRef";
053:
054: private static final String DATASOURCE = "dataSource";
055:
056: private static final String JDBCTEMPLATE_REF = "jdbcTemplateBeanRef";
057:
058: private static final String JDBCTEMPLATE = "jdbcTemplate";
059:
060: private static final String AUTHORITIES_BY_USERNAME_QUERY = "authoritiesByUsernameQuery";
061:
062: private static final String ROLE_PREFIX = "rolePrefix";
063:
064: private static final String USERNAME_BASED_PRIMARY_KEY = "usernameBasedPrimaryKey";
065:
066: private static final String PROPERTIES = "properties";
067:
068: private static final String RESOURCE = "resource";
069:
070: private static final String USER_PROPERTIES = "userProperties";
071:
072: private static final String USER_DEFINITION = "user-definition";
073:
074: private static final Object GRANTED_AUTHORITY = "granted-authority";
075:
076: private static final String USERNAME = "username";
077:
078: private static final String PASSWORD = "password";
079:
080: private static final String ENABLED = "enabled";
081:
082: private static final String GRANTED_AUTHORITY_REF = "granted-authority-ref";
083:
084: private static final String AUTHORITY = "authority";
085:
086: private static final String AUTHORITY_BEAN_REF = "authorityBeanRef";
087:
088: // ~ Method
089: // ================================================================================================
090: /**
091: *
092: */
093:
094: protected AbstractBeanDefinition parseInternal(Element element,
095: ParserContext parserContext) {
096: NodeList userDetailsServiceChildren = element.getChildNodes();
097: RootBeanDefinition userDetailsServiceDefinition = null;
098: for (int i = 0, n = userDetailsServiceChildren.getLength(); i < n; i++) {
099: Node userDetailsService = userDetailsServiceChildren
100: .item(i);
101:
102: if (JDBC.equals(userDetailsService.getLocalName())
103: && userDetailsService.getNodeType() == Node.ELEMENT_NODE) {
104: Element ele = (Element) userDetailsService;
105: userDetailsServiceDefinition = parseUserDetailsServiceJdbcDefinition(ele);
106: userDetailsServiceDefinition.setSource(parserContext
107: .extractSource(element));
108: }
109: if (PROPERTIES.equals(userDetailsService.getLocalName())
110: && userDetailsService.getNodeType() == Node.ELEMENT_NODE) {
111: Element ele = (Element) userDetailsService;
112:
113: userDetailsServiceDefinition = new RootBeanDefinition(
114: InMemoryDaoImpl.class);
115: userDetailsServiceDefinition.getPropertyValues()
116: .addPropertyValue(
117: USER_PROPERTIES,
118: new RuntimeBeanReference(
119: createPropertiesBeanDefinition(
120: ele, parserContext)));
121: userDetailsServiceDefinition.setSource(parserContext
122: .extractSource(element));
123: }
124: if (USER_DEFINITION.equals(userDetailsService
125: .getLocalName())
126: && userDetailsService.getNodeType() == Node.ELEMENT_NODE) {
127: Element ele = (Element) userDetailsService;
128:
129: // create a UserMap which interns uses UserMapEditor
130: userDetailsServiceDefinition = createUserDefinition(
131: ele, parserContext);
132: }
133: }
134: return userDetailsServiceDefinition;
135: }
136:
137: private RootBeanDefinition createUserDefinition(Element ele,
138: ParserContext parserContext) {
139: RootBeanDefinition definition = new RootBeanDefinition(
140: InMemoryDaoImpl.class);
141:
142: UserAttribute userAttribute = new UserAttribute();
143: UserMap userMap = new UserMap();
144:
145: setPassword(ele, userAttribute);
146: setEnabled(ele, userAttribute);
147: setAuthorities(ele, userAttribute);
148:
149: UserDetails user = new User(ele.getAttribute(USERNAME),
150: userAttribute.getPassword(), userAttribute.isEnabled(),
151: true, true, true, userAttribute.getAuthorities());
152: userMap.addUser(user);
153: definition.getPropertyValues().addPropertyValue("userMap",
154: userMap);
155: return definition;
156: }
157:
158: private String createPropertiesBeanDefinition(Element ele,
159: ParserContext parserContext) {
160: // properties element
161: RootBeanDefinition defintion = new RootBeanDefinition(
162: PropertiesFactoryBean.class);
163: String propertyValue = ele.getAttribute(RESOURCE);
164: defintion.getPropertyValues().addPropertyValue("location",
165: propertyValue);
166: defintion.setSource(parserContext.extractSource(ele));
167: return parserContext.getReaderContext()
168: .registerWithGeneratedName(defintion);
169: }
170:
171: protected static RootBeanDefinition createSampleUsersUsingProperties() {
172: // properties element
173: RootBeanDefinition defintion = new RootBeanDefinition(
174: PropertiesFactoryBean.class);
175: String location = "classpath:org/acegisecurity/config/user.properties";
176: defintion.getPropertyValues().addPropertyValue("location",
177: location);
178: return defintion;
179: }
180:
181: /**
182: *
183: * @param elementToParse
184: * @return
185: */
186: private RootBeanDefinition parseUserDetailsServiceJdbcDefinition(
187: Element elementToParse) {
188: // parse attributes
189: RootBeanDefinition definition = new RootBeanDefinition(
190: JdbcDaoImpl.class);
191: setPropertyIfAvailable(elementToParse, DATASOURCE_REF,
192: DATASOURCE, definition);
193: setPropertyIfAvailable(elementToParse, JDBCTEMPLATE_REF,
194: JDBCTEMPLATE, definition);
195: setPropertyIfAvailable(elementToParse,
196: AUTHORITIES_BY_USERNAME_QUERY,
197: AUTHORITIES_BY_USERNAME_QUERY, definition);
198: setPropertyIfAvailable(elementToParse, ROLE_PREFIX,
199: ROLE_PREFIX, definition);
200: setPropertyIfAvailable(elementToParse,
201: USERNAME_BASED_PRIMARY_KEY, USERNAME_BASED_PRIMARY_KEY,
202: definition);
203: return definition;
204: }
205:
206: protected void doParseProperties(Element element,
207: ParserContext parserContext, BeanDefinitionBuilder builder) {
208: Properties parsedProps = parserContext.getDelegate()
209: .parsePropsElement(element);
210: builder.addPropertyValue(PROPERTIES, parsedProps);
211: }
212:
213: /**
214: *
215: * @param element
216: * @param attribute
217: * @param property
218: * @param definition
219: */
220: private void setPropertyIfAvailable(Element element,
221: String attribute, String property,
222: RootBeanDefinition definition) {
223: String propertyValue = element.getAttribute(attribute);
224: if (StringUtils.hasText(propertyValue)) {
225: if (propertyValue.equals(DATASOURCE_REF)
226: || propertyValue.equals(JDBCTEMPLATE_REF)) {
227: definition.getPropertyValues().addPropertyValue(
228: property,
229: new RuntimeBeanReference(propertyValue));
230: } else {
231: definition.getPropertyValues().addPropertyValue(
232: property, propertyValue);
233: }
234: }
235: }
236:
237: private void setPassword(Element element,
238: UserAttribute userAttribute) {
239: String propertyValue = element.getAttribute(PASSWORD);
240: if (StringUtils.hasText(propertyValue)) {
241: userAttribute.setPassword(propertyValue);
242: }
243: }
244:
245: private void setEnabled(Element element, UserAttribute userAttribute) {
246: String propertyValue = element.getAttribute(ENABLED);
247: if (StringUtils.hasText(propertyValue)) {
248: if (propertyValue.equals("true")) {
249: userAttribute.setEnabled(true);
250: } else {
251: userAttribute.setEnabled(false);
252: }
253: }
254: }
255:
256: private void setAuthorities(Element ele, UserAttribute userAttribute) {
257: // get authorities
258: NodeList childNodes = ele.getChildNodes();
259:
260: ManagedList authorities = new ManagedList();
261:
262: for (int i = 0, n = childNodes.getLength(); i < n; i++) {
263: Node authorityNode = childNodes.item(i);
264:
265: if (GRANTED_AUTHORITY.equals(authorityNode.getLocalName())
266: && authorityNode.getNodeType() == Element.ELEMENT_NODE) {
267: Element propertyValue = (Element) authorityNode;
268: authorities.add(new GrantedAuthorityImpl(propertyValue
269: .getAttribute(AUTHORITY)));
270: }
271:
272: if (GRANTED_AUTHORITY_REF.equals(authorityNode
273: .getLocalName())
274: && authorityNode.getNodeType() == Element.ELEMENT_NODE) {
275: Element propertyValue = (Element) authorityNode;
276: String attribute = propertyValue
277: .getAttribute(AUTHORITY_BEAN_REF);
278: if (StringUtils.hasLength(attribute)) {
279: authorities
280: .add(new RuntimeBeanReference(attribute));
281: }
282: }
283: }
284: userAttribute.setAuthorities(authorities);
285: }
286:
287: }
|