001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010: package org.mmbase.security.implementation.basic;
011:
012: import org.mmbase.bridge.Query;
013:
014: import org.mmbase.module.core.*;
015: import org.mmbase.security.*;
016: import org.mmbase.security.SecurityException;
017:
018: import org.mmbase.util.logging.Logger;
019: import org.mmbase.util.logging.Logging;
020:
021: import java.util.*;
022: import java.io.InputStream;
023: import java.io.IOException;
024:
025: /**
026: * A very simple Authorization implementation, based an a property file. Every user will be present
027: * in this file as one property. Only the keys are of importance when authorizing, because it
028: * determines the 'possible users' and 'possible contexts'.
029: *
030: * Furthermore everybody is authorized to read, you may create if you are known, (so not anonymous),
031: * and you may edit, if you are either administrator or editing your 'own' node.
032: *
033: * @author Eduard Witteveen
034: * @author Michiel Meeuwissen
035: * @version $Id: OwnerAuthorization.java,v 1.14 2007/02/11 19:45:04 nklasens Exp $
036: */
037: public class OwnerAuthorization extends Authorization {
038:
039: private static final Logger log = Logging
040: .getLoggerInstance(OwnerAuthorization.class);
041:
042: private static MMObjectBuilder builder = null; // only to get Nodes from
043:
044: private Set<String> possibleContexts;
045:
046: private MMObjectNode getMMNode(int n) {
047: if (builder == null) {
048: MMBase mmb = MMBase.getMMBase();
049: builder = mmb.getMMObject("typedef"); // only because it always exists
050: if (builder == null)
051: throw new SecurityException(
052: "Builder 'typedef'not found.");
053: }
054: MMObjectNode node = builder.getNode(n);
055: if (node == null)
056: throw new SecurityException("Node '" + n + "' not found");
057: return node;
058: }
059:
060: public void load() {
061: log.service("using: '" + configResource
062: + "' as config file for authentication");
063: InputStream in = MMBaseCopConfig.securityLoader
064: .getResourceAsStream(configResource);
065: if (in == null) {
066: log.warn("No '" + configResource
067: + "', nobody will be authorized.");
068: }
069:
070: Properties accounts = new Properties();
071:
072: if (in != null) {
073: try {
074: accounts.load(in);
075: } catch (IOException io) {
076: log.error("Could read accounts! " + io, io);
077: }
078: } else {
079: log.warn("Could not find accounts!");
080: }
081: possibleContexts = new HashSet<String>();
082: for (Object key : accounts.keySet()) {
083: possibleContexts.add((String) key);
084: }
085: log.debug("file for accounts loaded");
086: }
087:
088: public void create(UserContext user, int nodeNumber) {
089: if (manager.getActive()) { // else don't touch.
090: MMObjectNode node = getMMNode(nodeNumber);
091: node.setValue("owner", user.getIdentifier());
092: node.commit();
093: }
094: }
095:
096: public void update(UserContext user, int nodeNumber) {
097: if (manager.getActive()) {
098: MMObjectNode node = getMMNode(nodeNumber);
099: node.setValue("owner", user.getIdentifier());
100: node.commit();
101: }
102: }
103:
104: public void remove(UserContext user, int node) {
105: }
106:
107: public boolean check(UserContext user, int nodeNumber,
108: Operation operation) {
109: // if we don't do security, then we are allowed to do everything.
110: if (!manager.getActive()) {
111: log.trace("security is not active. permitting operation");
112: return true;
113: }
114:
115: if (log.isDebugEnabled()) {
116: log.trace("checking user: " + user.getIdentifier()
117: + " operation: " + operation + " node: "
118: + nodeNumber);
119: }
120:
121: boolean permitted = false;
122:
123: // if we are admin, then everything is permitted as well....
124: if (user.getRank() == Rank.ADMIN) {
125: log.trace("User with rank " + Rank.ADMIN
126: + " always has all rights.");
127: return true;
128: }
129:
130: switch (operation.getInt()) {
131: // say we may always create, if we are authenticated.
132: case Operation.CREATE_INT:
133: // nah, we may always view other nodes.,....
134: case Operation.READ_INT:
135: permitted = true;
136: break;
137: // same rights as writing, no break
138: case Operation.DELETE_INT:
139: // dont think so when we are anonymous...
140: case Operation.WRITE_INT:
141: case Operation.CHANGE_CONTEXT_INT:
142: // we are logged in, check if we may edit this node,....
143: if (user.getRank() != Rank.ANONYMOUS) {
144: MMObjectNode node = getMMNode(nodeNumber);
145: String ownerName = node.getStringValue("owner");
146: if (log.isDebugEnabled()) {
147: log.debug("Owner of checking field is:'"
148: + ownerName + "' and user is '"
149: + user.getIdentifier() + "'");
150: }
151: permitted = ownerName.equals(user.getIdentifier());
152: } else {
153: // if user is anonymous.....
154: permitted = false;
155: }
156: break;
157: default:
158: throw new SecurityException("Operation '" + operation
159: + "' on node '" + nodeNumber
160: + "' was NOT permitted to user '" + user
161: + "' (Operation unknown?)");
162: }
163:
164: if (log.isDebugEnabled()) {
165: if (permitted) {
166: log.trace("operation was permitted");
167: } else {
168: log
169: .debug(" user: " + user.getIdentifier()
170: + " operation: " + operation
171: + " node: " + nodeNumber
172: + " operation was NOT permitted");
173: }
174: }
175: return permitted;
176: }
177:
178: public boolean check(UserContext user, int nodeNumber,
179: int srcNodeNumber, int dstNodeNumber, Operation operation) {
180: if (manager.getActive()) {
181: if (user.getRank() == Rank.ANONYMOUS) {
182: if (log.isDebugEnabled()) {
183: log.debug(" user: " + user.getIdentifier()
184: + " operation: " + operation + " node: "
185: + nodeNumber
186: + " operation was NOT permitted");
187: }
188: return false;
189: }
190: }
191: return true;
192: }
193:
194: public String getContext(UserContext user, int nodeNumber)
195: throws SecurityException {
196: verify(user, nodeNumber, Operation.READ);
197: // and get the value...
198: MMObjectNode node = getMMNode(nodeNumber);
199: return node.getStringValue("owner");
200: }
201:
202: /**
203: * This method does nothing, except from checking if the setContext was valid..
204: */
205: public void setContext(UserContext user, int nodeNumber,
206: String context) throws SecurityException {
207: // check if is a valid context for us..
208: Set<String> possible = getPossibleContexts(user, nodeNumber);
209: if (!possible.contains(context)) {
210: throw new SecurityException("could not set the context to "
211: + context + " for node #" + nodeNumber
212: + " by user: " + user + "not a valid context");
213: }
214:
215: // check if this operation is allowed? (should also be done somewhere else, but we can never be sure enough)
216: verify(user, nodeNumber, Operation.CHANGE_CONTEXT);
217:
218: // well now really set it...
219: MMObjectNode node = getMMNode(nodeNumber);
220: node.setValue("owner", user.getIdentifier());
221: node.commit();
222: if (log.isServiceEnabled()) {
223: log.service("changed context settings of node #"
224: + nodeNumber + " to context: " + context
225: + " by user: " + user);
226: }
227: }
228:
229: /**
230: * Returns a list of all users in accounts.properties
231: */
232: public Set<String> getPossibleContexts(UserContext user,
233: int nodeNumber)
234: throws org.mmbase.security.SecurityException {
235:
236: if (possibleContexts == null) {
237: log.warn("Security not loaded");
238: return new HashSet<String>();
239: } else {
240: return possibleContexts;
241: }
242: }
243:
244: public QueryCheck check(UserContext user, Query query,
245: Operation operation) {
246: if (user.getRank().getInt() >= Rank.ADMIN.getInt()) {
247: return COMPLETE_CHECK;
248: }
249: if (operation == Operation.READ) {
250: return COMPLETE_CHECK;
251: } else {
252: return NO_CHECK;
253: }
254: }
255: }
|