001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. The ASF licenses this file to You
004: * under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License. For additional information regarding
015: * copyright in this work, please see the NOTICE file in the top level
016: * directory of this distribution.
017: */
018: package org.apache.roller.webservices.adminapi;
019:
020: import java.io.IOException;
021: import java.io.Reader;
022: import java.util.ArrayList;
023: import java.util.Collections;
024: import java.util.Iterator;
025: import java.util.List;
026: import javax.servlet.http.HttpServletRequest;
027: import org.jdom.Document;
028: import org.jdom.JDOMException;
029: import org.apache.roller.RollerException;
030: import org.apache.roller.business.UserManager;
031: import org.apache.roller.pojos.PermissionsData;
032: import org.apache.roller.pojos.UserData;
033: import org.apache.roller.pojos.WebsiteData;
034: import org.apache.roller.util.cache.CacheManager;
035: import org.apache.roller.webservices.adminapi.sdk.Entry;
036: import org.apache.roller.webservices.adminapi.sdk.EntrySet;
037: import org.apache.roller.webservices.adminapi.sdk.MemberEntry;
038: import org.apache.roller.webservices.adminapi.sdk.MemberEntrySet;
039: import org.apache.roller.webservices.adminapi.sdk.UnexpectedRootElementException;
040:
041: /**
042: * This class handles requests concerning Roller weblog membership (groups).
043: */
044: class RollerMemberHandler extends Handler {
045: static class MemberURI extends URI {
046: private String username;
047: private String handle;
048:
049: public MemberURI(HttpServletRequest req)
050: throws BadRequestException {
051: super (req);
052: String entryId = getEntryId();
053: if (entryId == null) {
054: username = null;
055: handle = null;
056: } else {
057: String[] entryIds = entryId.split("/");
058: if (entryIds == null || entryIds.length == 0) {
059: throw new BadRequestException(
060: "ERROR: Invalid path info: "
061: + req.getPathInfo());
062: }
063: handle = entryIds[0];
064: if (entryIds.length > 1) {
065: username = entryIds[1];
066: }
067: }
068: }
069:
070: public boolean hasUsername() {
071: return getUsername() != null;
072: }
073:
074: public String getUsername() {
075: return username;
076: }
077:
078: private void setUsername(String username) {
079: this .username = username;
080: }
081:
082: public String getHandle() {
083: return handle;
084: }
085:
086: private void setHandle(String handle) {
087: this .handle = handle;
088: }
089: }
090:
091: private URI memberUri;
092:
093: public RollerMemberHandler(HttpServletRequest request)
094: throws HandlerException {
095: super (request);
096: memberUri = new MemberURI(request);
097: }
098:
099: protected EntrySet getEntrySet(Document d)
100: throws UnexpectedRootElementException {
101: return new MemberEntrySet(d, getUrlPrefix());
102: }
103:
104: protected URI getUri() {
105: return memberUri;
106: }
107:
108: public EntrySet processGet() throws HandlerException {
109: if (getUri().isCollection()) {
110: return getCollection();
111: } else if (getUri().isEntry()) {
112: return getEntry();
113: } else {
114: throw new BadRequestException("ERROR: Unknown GET URI type");
115: }
116: }
117:
118: public EntrySet processPost(Reader r) throws HandlerException {
119: if (getUri().isCollection()) {
120: return postCollection(r);
121: } else {
122: throw new BadRequestException(
123: "ERROR: Unknown POST URI type");
124: }
125: }
126:
127: public EntrySet processPut(Reader r) throws HandlerException {
128: if (getUri().isCollection()) {
129: return putCollection(r);
130: } else if (getUri().isEntry()) {
131: return putEntry(r);
132: } else {
133: throw new BadRequestException("ERROR: Unknown PUT URI type");
134: }
135: }
136:
137: public EntrySet processDelete() throws HandlerException {
138: if (getUri().isEntry()) {
139: return deleteEntry();
140: } else {
141: throw new BadRequestException(
142: "ERROR: Unknown DELETE URI type");
143: }
144: }
145:
146: private EntrySet getCollection() throws HandlerException {
147: // get all permissions: for all users, for all websites
148: try {
149: List users = getRoller().getUserManager().getUsers(null,
150: null, null, 0, -1);
151: List perms = new ArrayList();
152: for (Iterator i = users.iterator(); i.hasNext();) {
153: UserData user = (UserData) i.next();
154: List permissions = getRoller().getUserManager()
155: .getAllPermissions(user);
156: for (Iterator j = permissions.iterator(); j.hasNext();) {
157: PermissionsData pd = (PermissionsData) j.next();
158: perms.add(pd);
159: }
160: }
161: EntrySet es = toMemberEntrySet((PermissionsData[]) perms
162: .toArray(new PermissionsData[0]));
163: return es;
164: } catch (RollerException re) {
165: throw new InternalException(
166: "ERROR: Could not get member collection", re);
167: }
168: }
169:
170: private EntrySet getEntry() throws HandlerException {
171: MemberURI muri = (MemberURI) getUri();
172: String handle = muri.getHandle();
173: String username = muri.getUsername();
174:
175: try {
176: List perms;
177: if (username == null) {
178: //get all entries for the given website handle
179: WebsiteData wd = getWebsiteData(handle);
180: if (wd == null) {
181: throw new NotFoundException(
182: "ERROR: Unknown weblog handle: " + handle);
183: }
184: perms = getRoller().getUserManager().getAllPermissions(
185: wd);
186: } else {
187: //get all entries for the given website handle & username
188: WebsiteData wd = getWebsiteData(handle);
189: if (wd == null) {
190: throw new NotFoundException(
191: "ERROR: Unknown weblog handle: " + handle);
192: }
193: UserData ud = getUserData(username);
194: if (ud == null) {
195: throw new NotFoundException(
196: "ERROR: Unknown user name: " + username);
197: }
198: PermissionsData pd = getRoller().getUserManager()
199: .getPermissions(wd, ud);
200: if (pd == null) {
201: throw new NotFoundException(
202: "ERROR: Could not get permissions for user name: "
203: + username + ", handle: " + handle);
204: }
205: perms = Collections.singletonList(pd);
206: }
207:
208: EntrySet es = toMemberEntrySet((PermissionsData[]) perms
209: .toArray(new PermissionsData[0]));
210: return es;
211: } catch (RollerException re) {
212: throw new InternalException(
213: "ERROR: Could not get entry for handle: " + handle
214: + ", username: " + username, re);
215: }
216: }
217:
218: private EntrySet postCollection(Reader r) throws HandlerException {
219: EntrySet c = getEntrySet(r);
220: if (c.isEmpty()) {
221: throw new BadRequestException("ERROR: No entries");
222: }
223: c = createMembers((MemberEntrySet) c);
224:
225: return c;
226: }
227:
228: private EntrySet putCollection(Reader r) throws HandlerException {
229: EntrySet c = getEntrySet(r);
230: if (c.isEmpty()) {
231: throw new BadRequestException("ERROR: No entries");
232: }
233: c = updateMembers((MemberEntrySet) c);
234:
235: return c;
236: }
237:
238: private EntrySet putEntry(Reader r) throws HandlerException {
239: EntrySet c = getEntrySet(r);
240: if (c.isEmpty()) {
241: throw new BadRequestException("ERROR: No entries");
242: }
243: if (c.getEntries().length > 1) {
244: throw new BadRequestException(
245: "ERROR: Cannot put >1 entries per request");
246: }
247:
248: // only one entry
249: // if there's zero entries, this is a nop
250: MemberEntry entry = (MemberEntry) c.getEntries()[0];
251:
252: MemberURI muri = (MemberURI) getUri();
253:
254: // get handle
255: // if there's no handle in the entry, set it
256: // if the entry and URI handles do not match, exception
257: String handle = muri.getHandle();
258: if (entry.getHandle() == null) {
259: entry.setHandle(handle);
260: } else if (!entry.getHandle().equals(handle)) {
261: throw new BadRequestException(
262: "ERROR: URI and entry handle do not match");
263: }
264:
265: // get username
266: // if there's no name in the entry or the URI, exception
267: // if there's no name in the entry, set it
268: // if the names in the entry and URI do not match, exception
269: String username = muri.getUsername();
270: if (entry.getName() == null) {
271: if (username == null) {
272: throw new BadRequestException(
273: "ERROR: No user name in URI or entry");
274: }
275: entry.setName(username);
276: } else if (username != null
277: && !entry.getName().equals(username)) {
278: throw new BadRequestException(
279: "ERROR: URI and entry user name do not match");
280: }
281:
282: c = updateMembers((MemberEntrySet) c);
283:
284: return c;
285: }
286:
287: private MemberEntrySet createMembers(MemberEntrySet c)
288: throws HandlerException {
289: try {
290: UserManager mgr = getRoller().getUserManager();
291:
292: List permissionsDatas = new ArrayList();
293: for (int i = 0; i < c.getEntries().length; i++) {
294: MemberEntry entry = (MemberEntry) c.getEntries()[i];
295: PermissionsData pd = toPermissionsData(entry);
296: mgr.savePermissions(pd);
297: getRoller().flush();
298: CacheManager.invalidate(pd.getUser());
299: CacheManager.invalidate(pd.getWebsite());
300: permissionsDatas.add(pd);
301: }
302: return toMemberEntrySet((PermissionsData[]) permissionsDatas
303: .toArray(new PermissionsData[0]));
304: } catch (RollerException re) {
305: throw new InternalException(
306: "ERROR: Could not create members", re);
307: }
308: }
309:
310: private PermissionsData toPermissionsData(MemberEntry entry)
311: throws HandlerException {
312: UserData ud = getUserData(entry.getName());
313: WebsiteData wd = getWebsiteData(entry.getHandle());
314: PermissionsData pd = new PermissionsData();
315: pd.setUser(ud);
316: pd.setWebsite(wd);
317: pd.setPermissionMask(stringToMask(entry.getPermission()));
318: pd.setPending(false);
319:
320: return pd;
321: }
322:
323: private PermissionsData getPermissionsData(MemberEntry entry)
324: throws HandlerException {
325: return getPermissionsData(entry.getHandle(), entry.getName());
326: }
327:
328: private PermissionsData getPermissionsData(String handle,
329: String username) throws HandlerException {
330: try {
331: UserData ud = getUserData(username);
332: WebsiteData wd = getWebsiteData(handle);
333: PermissionsData pd = getRoller().getUserManager()
334: .getPermissions(wd, ud);
335:
336: return pd;
337: } catch (RollerException re) {
338: throw new InternalException(
339: "ERROR: Could not get permissions data for weblog handle: "
340: + handle + ", user name: " + username, re);
341: }
342: }
343:
344: private MemberEntrySet updateMembers(MemberEntrySet c)
345: throws HandlerException {
346: List permissionsDatas = new ArrayList();
347: for (int i = 0; i < c.getEntries().length; i++) {
348: MemberEntry entry = (MemberEntry) c.getEntries()[i];
349: PermissionsData pd = getPermissionsData(entry);
350: if (pd == null) {
351: throw new NotFoundException(
352: "ERROR: Permissions do not exist for weblog handle: "
353: + entry.getHandle() + ", user name: "
354: + entry.getName());
355: }
356: updatePermissionsData(pd, entry);
357: permissionsDatas.add(pd);
358: }
359: return toMemberEntrySet((PermissionsData[]) permissionsDatas
360: .toArray(new PermissionsData[0]));
361: }
362:
363: private void updatePermissionsData(PermissionsData pd,
364: MemberEntry entry) throws HandlerException {
365: // only permission can be updated
366:
367: if (entry.getPermission() != null) {
368: pd.setPermissionMask(stringToMask(entry.getPermission()));
369: }
370:
371: try {
372: UserData ud = getUserData(entry.getName());
373: WebsiteData wd = getWebsiteData(entry.getHandle());
374:
375: UserManager mgr = getRoller().getUserManager();
376: mgr.savePermissions(pd);
377: getRoller().flush();
378: CacheManager.invalidate(ud);
379: CacheManager.invalidate(wd);
380: } catch (RollerException re) {
381: throw new InternalException(
382: "ERROR: Could not update permissions data", re);
383: }
384: }
385:
386: private EntrySet deleteEntry() throws HandlerException {
387: MemberURI muri = (MemberURI) getUri();
388:
389: String handle = muri.getHandle();
390: String username = muri.getUsername();
391:
392: if (username == null) {
393: throw new BadRequestException(
394: "ERROR: No user name supplied in URI");
395: }
396:
397: try {
398: PermissionsData pd = getPermissionsData(handle, username);
399: PermissionsData[] pds;
400: if (pd == null) {
401: throw new NotFoundException(
402: "ERROR: Permissions do not exist for weblog handle: "
403: + handle + ", user name: " + username);
404: }
405: pds = new PermissionsData[] { pd };
406:
407: UserManager mgr = getRoller().getUserManager();
408: mgr.removePermissions(pd);
409: getRoller().flush();
410:
411: UserData ud = getUserData(username);
412: CacheManager.invalidate(ud);
413: WebsiteData wd = getWebsiteData(handle);
414: CacheManager.invalidate(wd);
415:
416: EntrySet es = toMemberEntrySet(pds);
417: return es;
418: } catch (RollerException re) {
419: throw new InternalException(
420: "ERROR: Could not delete entry", re);
421: }
422: }
423:
424: private MemberEntry toMemberEntry(PermissionsData pd) {
425: if (pd == null) {
426: throw new NullPointerException(
427: "ERROR: Null permission data not allowed");
428: }
429: MemberEntry me = new MemberEntry(pd.getWebsite().getHandle(),
430: pd.getUser().getUserName(), getUrlPrefix());
431: me.setPermission(maskToString(pd.getPermissionMask()));
432:
433: return me;
434: }
435:
436: private MemberEntrySet toMemberEntrySet(PermissionsData[] pds) {
437: if (pds == null) {
438: throw new NullPointerException(
439: "ERROR: Null permission data not allowed");
440: }
441:
442: List entries = new ArrayList();
443: for (int i = 0; i < pds.length; i++) {
444: PermissionsData pd = pds[i];
445: Entry entry = toMemberEntry(pd);
446: entries.add(entry);
447: }
448: MemberEntrySet mes = new MemberEntrySet(getUrlPrefix());
449: mes.setEntries((Entry[]) entries.toArray(new Entry[0]));
450:
451: return mes;
452: }
453:
454: private static String maskToString(short mask) {
455: if (mask == PermissionsData.ADMIN) {
456: return MemberEntry.Permissions.ADMIN;
457: }
458: if (mask == PermissionsData.AUTHOR) {
459: return MemberEntry.Permissions.AUTHOR;
460: }
461: if (mask == PermissionsData.LIMITED) {
462: return MemberEntry.Permissions.LIMITED;
463: }
464: return null;
465: }
466:
467: private static short stringToMask(String s) {
468: if (s == null) {
469: throw new NullPointerException(
470: "ERROR: Null string not allowed");
471: }
472: if (s.equalsIgnoreCase(MemberEntry.Permissions.ADMIN)) {
473: return PermissionsData.ADMIN;
474: }
475: if (s.equalsIgnoreCase(MemberEntry.Permissions.AUTHOR)) {
476: return PermissionsData.AUTHOR;
477: }
478: if (s.equalsIgnoreCase(MemberEntry.Permissions.LIMITED)) {
479: return PermissionsData.LIMITED;
480: }
481: return 0;
482: }
483: }
|