001: package org.obe.server.j2ee.repository;
002:
003: import java.io.IOException;
004: import java.io.InputStream;
005: import java.security.Principal;
006: import java.security.acl.Group;
007: import java.util.*;
008: import org.apache.commons.logging.Log;
009: import org.apache.commons.logging.LogFactory;
010: import org.obe.client.api.repository.ObjectNotFoundException;
011: import org.obe.client.api.repository.RepositoryException;
012: import org.obe.runtime.participant.BasicGroup;
013: import org.obe.runtime.participant.BasicPrincipal;
014: import org.obe.spi.model.ProcessInstance;
015: import org.obe.spi.service.SecurityRealm;
016: import org.obe.spi.service.ServiceManager;
017:
018: /**
019: * A realm implementation to match the JBoss UsersRolesLoginModule.
020: *
021: * @author Adrian Price
022: */
023: public class JBossUsersRolesRealm implements SecurityRealm {
024: private static final String USER_PROPS = "users.properties";
025: private static final String ROLE_PROPS = "roles.properties";
026: private static final Log _logger = LogFactory
027: .getLog(JBossUsersRolesRealm.class);
028: private final ServiceManager _svcMgr;
029: private final Map _principals = new HashMap();
030:
031: private static Properties loadProperties(String propFile)
032: throws IOException, RepositoryException {
033:
034: InputStream in = JBossUsersRolesRealm.class.getClassLoader()
035: .getResourceAsStream(propFile);
036: if (in == null) {
037: throw new RepositoryException("Properties file " + propFile
038: + " not found");
039: }
040: Properties props = new Properties();
041: try {
042: props.load(in);
043: } finally {
044: in.close();
045: }
046: return props;
047: }
048:
049: public JBossUsersRolesRealm(ServiceManager svcMgr) {
050: _svcMgr = svcMgr;
051: }
052:
053: public void init() throws IOException, RepositoryException {
054: // Load the users.
055: Properties users = loadProperties(USER_PROPS);
056: Enumeration e = users.elements();
057: while (e.hasMoreElements()) {
058: String name = (String) e.nextElement();
059: Principal principal = new BasicPrincipal(name);
060: _principals.put(name, principal);
061:
062: if (_logger.isDebugEnabled())
063: _logger.debug("Loaded " + principal);
064: }
065:
066: // Load the JAAS groups, ignoring the J2EE security roles.
067: Properties roles = loadProperties(ROLE_PROPS);
068: Iterator i = roles.entrySet().iterator();
069: while (i.hasNext()) {
070: Map.Entry entry = (Map.Entry) i.next();
071: String key = (String) entry.getKey();
072: String value = (String) entry.getValue();
073:
074: // Syntax is member[.GroupName][=csv]. Default GroupName is 'Roles'.
075: int index = key.indexOf('.');
076: String groupName = index == -1 ? "Roles" : key
077: .substring(index + 1);
078:
079: // We don't care about the special JBoss 'Roles' Groups, because
080: // they aren't real security Principals.
081: if (groupName.equals("Roles")) {
082: if (_logger.isDebugEnabled())
083: _logger.debug("Skipped 'Roles' Group: " + key);
084: continue;
085: }
086:
087: // Retrieve or create the member to which this Group refers.
088: String memberName = index == -1 ? key : key.substring(0,
089: index);
090: Principal member = (Principal) _principals.get(memberName);
091: if (member == null) {
092: // If the member isn't yet known, it must be a new Group.
093: member = new BasicGroup(memberName);
094: _principals.put(memberName, member);
095: }
096:
097: // Retrieve or create the Group to which this member belongs.
098: Principal principal = (Principal) _principals
099: .get(groupName);
100: Group group;
101: if (principal == null) {
102: group = new BasicGroup(groupName);
103: _principals.put(groupName, group);
104: } else if (principal instanceof Group) {
105: group = (Group) principal;
106: } else {
107: throw new RepositoryException("Entry " + key
108: + ": existing principal name '" + groupName
109: + "' does not refer to a Group");
110: }
111:
112: // Parse the group membership.
113: parseGroupMembers(member, value, group);
114:
115: if (_logger.isDebugEnabled())
116: _logger.debug("Loaded groups for " + memberName);
117: }
118:
119: // If debug is enabled, dump the entire Principal / Group structure.
120: if (_logger.isDebugEnabled()) {
121: i = _principals.values().iterator();
122: while (i.hasNext()) {
123: _logger.debug(i.next());
124: }
125: }
126: }
127:
128: private void parseGroupMembers(Principal member, String value,
129: Group group) {
130:
131: // Make sure the member really is a member of the group.
132: // This logic enables us to use a shorthand notation for group
133: // membership. Without it, roles.properties would have to provide the
134: // entire group membership each time it is referenced. This notation
135: // allows us to build up group membership by inference.
136: group.addMember(member);
137:
138: // Add the other members, if they are defined.
139: if (value != null && value.length() > 0) {
140: StringTokenizer tokenizer = new StringTokenizer(value, ",");
141: while (tokenizer.hasMoreTokens()) {
142: String token = tokenizer.nextToken();
143:
144: // Members of non 'Roles' Groups are real security Principals.
145: // Unknown Principals are assumed to be new Groups.
146: Principal p = (Principal) _principals.get(token);
147: if (p == null)
148: _principals.put(token, p = new BasicGroup(token));
149:
150: group.addMember(p);
151: }
152: }
153: }
154:
155: public void exit() {
156: _principals.clear();
157: }
158:
159: public ServiceManager getServiceManager() {
160: return _svcMgr;
161: }
162:
163: public String getServiceName() {
164: return SERVICE_NAME;
165: }
166:
167: public Principal findPrincipal(String name)
168: throws RepositoryException {
169: Principal principal = (Principal) _principals.get(name);
170: if (principal == null)
171: throw new ObjectNotFoundException(name);
172: return principal;
173: }
174:
175: public Principal[] findPrincipals(int mask)
176: throws RepositoryException {
177: List principals = new ArrayList(_principals.size());
178: boolean findUsers = (mask & USER) != 0;
179: boolean findGroups = (mask & GROUP) != 0;
180: for (Iterator i = _principals.values().iterator(); i.hasNext();) {
181: Principal principal = (Principal) i.next();
182: if (principal instanceof Group) {
183: if (findGroups)
184: principals.add(principal);
185: } else if (findUsers) {
186: principals.add(principal);
187: }
188: }
189: return (Principal[]) principals
190: .toArray(new Principal[principals.size()]);
191: }
192:
193: public Principal[] resolveParticipants(String name,
194: ProcessInstance processInstance) throws RepositoryException {
195:
196: // Make sure the principal actually exists in the realm.
197: Principal participant = findPrincipal(name);
198:
199: return new Principal[] { participant };
200: }
201: }
|