KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > roller > presentation > atomapi > RollerAtomHandler


1 /*
2  * Copyright 2005 David M Johnson (For RSS and Atom In Action)
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.roller.presentation.atomapi;
17
18 import java.io.File JavaDoc;
19 import java.io.FileInputStream JavaDoc;
20 import java.io.FileOutputStream JavaDoc;
21 import java.io.InputStream JavaDoc;
22 import java.sql.Timestamp JavaDoc;
23 import java.text.SimpleDateFormat JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Date JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.StringTokenizer JavaDoc;
29
30 import javax.servlet.http.HttpServletRequest JavaDoc;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.apache.struts.util.RequestUtils;
35 import org.roller.model.FileManager;
36 import org.roller.model.Roller;
37 import org.roller.model.WeblogManager;
38 import org.roller.pojos.UserData;
39 import org.roller.pojos.WeblogCategoryData;
40 import org.roller.pojos.WeblogEntryData;
41 import org.roller.pojos.WebsiteData;
42 import org.roller.presentation.LoginServlet;
43 import org.roller.presentation.RollerContext;
44 import org.roller.util.RollerMessages;
45 import org.roller.util.Utilities;
46
47 import com.sun.syndication.feed.atom.Content;
48 import com.sun.syndication.feed.atom.Entry;
49 import com.sun.syndication.feed.atom.Link;
50 import com.sun.syndication.io.impl.Base64;
51
52 /**
53  * Roller's Atom Protocol implementation.
54  * <pre>
55  * Here are the URIs suppored:
56  *
57  * URI type URI form Handled by
58  * -------- -------- ----------
59  * Introspection URI /blog-name getIntrosection()
60  * Collection URI /blog-name/<collection-name> getCollection()
61  * Collection-next URI /blog-name/<collection-name>/id getCollection()
62  * Member URI /blog-name/<object-name> post<object-name>()
63  * Member URI /blog-name/<object-name>/id get<object-name>()
64  * Member URI /blog-name/<object-name>/id put<object-name>()
65  * Member URI /blog-name/<object-name>/id delete<object-name>()
66  *
67  * Until group blogging is supported username == blogname.
68  *
69  * Collection-names Object-names
70  * ---------------- ------------
71  * entries entry
72  * resources resource
73  * categories categories
74  * soon:
75  * users user
76  * templates template
77  * </pre>
78  *
79  * @author David M Johnson
80  */

81 public class RollerAtomHandler implements AtomHandler
82 {
83     private HttpServletRequest JavaDoc mRequest;
84     private Roller mRoller;
85     private RollerContext mRollerContext;
86     private String JavaDoc mUsername;
87     private int mMaxEntries = 20;
88     //private MessageDigest md5Helper = null;
89
//private MD5Encoder md5Encoder = new MD5Encoder();
90

91     private static Log mLogger =
92         LogFactory.getFactory().getInstance(RollerAtomHandler.class);
93     
94     private SimpleDateFormat JavaDoc timestampFormat =
95         new SimpleDateFormat JavaDoc("yyyyMMddHHmmss" );
96
97     //---------------------------------------------------------------- construction
98

99     /**
100      * Create Atom handler for a request and attempt to authenticate user.
101      * If user is authenticated, then getAuthenticatedUsername() will return
102      * then user's name, otherwise it will return null.
103      */

104     public RollerAtomHandler(HttpServletRequest JavaDoc request)
105     {
106         mRequest = request;
107         mRoller = RollerContext.getRoller(request);
108         mRollerContext = RollerContext.getRollerContext(request);
109         
110         // TODO: decide what to do about authentication, is WSSE going to fly?
111
mUsername = authenticateWSSE(request);
112         //mUsername = authenticateBASIC(request);
113

114         if (mUsername != null)
115         {
116             try
117             {
118                 UserData user = mRoller.getUserManager().getUser(mUsername);
119                 mRoller.setUser(user);
120             }
121             catch (Exception JavaDoc e)
122             {
123                 mLogger.error("ERROR: setting user", e);
124             }
125         }
126         // try
127
// {
128
// md5Helper = MessageDigest.getInstance("MD5");
129
// }
130
// catch (NoSuchAlgorithmException e)
131
// {
132
// mLogger.debug("ERROR creating MD5 helper", e);
133
// }
134
}
135     
136     /**
137      * Return username of authenticated user or null if there is none.
138      */

139     public String JavaDoc getAuthenticatedUsername()
140     {
141         return mUsername;
142     }
143   
144     //---------------------------------------------------------------- introspection
145

146     /**
147      * Return Atom service document for site, getting blog-name from pathInfo.
148      * Since a user can (currently) have only one blog, one workspace is returned.
149      * The workspace will contain collections for entries, categories and resources.
150      */

151     public AtomService getIntrospection(String JavaDoc[] pathInfo) throws Exception JavaDoc
152     {
153         if (pathInfo.length == 1)
154         {
155             String JavaDoc username = pathInfo[0];
156             String JavaDoc absUrl = mRollerContext.getAbsoluteContextUrl(mRequest);
157             
158             AtomService service = new AtomService();
159
160             AtomService.Workspace workspace = new AtomService.Workspace();
161             workspace.setTitle("Workspace: Collections for " + username);
162             service.addWorkspace(workspace);
163
164             AtomService.Collection entryCol = new AtomService.Collection();
165             entryCol.setTitle("Collection: Weblog Entries for " + username);
166             entryCol.setContents("entries");
167             entryCol.setHref(absUrl + "/atom/"+mUsername+"/entries");
168             workspace.addCollection(entryCol);
169             
170             AtomService.Collection catCol = new AtomService.Collection();
171             catCol.setTitle("Collection: Categories for " + username);
172             catCol.setContents("categories");
173             catCol.setHref(absUrl + "/atom/"+mUsername+"/categories");
174             workspace.addCollection(catCol);
175             
176             AtomService.Collection uploadCol = new AtomService.Collection();
177             uploadCol.setTitle("Collection: File uploads for " + username);
178             uploadCol.setContents("generic");
179             uploadCol.setHref(absUrl + "/atom/"+mUsername+"/resources");
180             workspace.addCollection(uploadCol);
181             
182             return service;
183         }
184         throw new Exception JavaDoc("ERROR: bad URL in getIntrospection()");
185     }
186     
187     //----------------------------------------------------------------- collections
188

189     /**
190      * Returns collection specified by pathInfo with no date range specified.
191      * Just calls the other getCollection(), but with offset = -1.
192      */

193     public AtomCollection getCollection(String JavaDoc[] pathInfo) throws Exception JavaDoc
194     {
195         return getCollection(pathInfo, null, new Date JavaDoc(), -1);
196     }
197
198     /**
199      * Returns collection specified by pathInfo, constrained by a date range and
200      * starting at an offset within the collection.Returns 20 items at a time.
201      * <pre>
202      * Supports these three collection URI forms:
203      * /<blog-name>/entries
204      * /<blog-name>/resources
205      * /<blog-name>/categories
206      * </pre>
207      * @param pathInfo Path info from URI
208      * @param start Don't include members updated before this date (null allowed)
209      * @param end Don't include members updated after this date (null allowed)
210      * @param offset Offset within collection (for paging)
211      */

212     public AtomCollection getCollection(
213             String JavaDoc[] pathInfo, Date JavaDoc start, Date JavaDoc end, int offset)
214         throws Exception JavaDoc
215     {
216         if (pathInfo.length > 0 && pathInfo[1].equals("entries"))
217         {
218             return getCollectionOfEntries(pathInfo, start, end, offset);
219         }
220         else if (pathInfo.length > 0 && pathInfo[1].equals("resources"))
221         {
222             return getCollectionOfResources(pathInfo, start, end, offset);
223         }
224         else if (pathInfo.length > 0 && pathInfo[1].equals("categories"))
225         {
226             return getCollectionOfCategories(pathInfo, start, end, offset);
227         }
228         throw new Exception JavaDoc("ERROR: bad URL in getCollection()");
229     }
230
231     /**
232      * Helper method that returns collection of entries, called by getCollection().
233      */

234     public AtomCollection getCollectionOfEntries(
235             String JavaDoc[] pathInfo, Date JavaDoc start, Date JavaDoc end, int offset)
236         throws Exception JavaDoc
237     {
238         String JavaDoc username = pathInfo[0];
239         String JavaDoc absUrl = mRollerContext.getAbsoluteContextUrl(mRequest);
240         WebsiteData website = mRoller.getUserManager().getWebsite(username);
241         List JavaDoc entries = null;
242         if (canView(website))
243         {
244             if (pathInfo.length == 2) // handle /blogname/entries
245
{
246                 // return most recent blog entries
247
if (offset == -1)
248                 {
249                     entries = mRoller.getWeblogManager().getWeblogEntries(
250                             website, // website
251
start, // startDate
252
end, // endDate
253
null, // catName
254
WeblogManager.ALL, // status
255
new Integer JavaDoc(mMaxEntries + 1)); // maxEntries
256
}
257                 else
258                 {
259                     entries = mRoller.getWeblogManager().getWeblogEntries(
260                             website, // website
261
start, // startDate
262
end, // endDate
263
null, // catName
264
WeblogManager.ALL, // status
265
offset, // offset (for range paging)
266
mMaxEntries + 1); // maxEntries
267
}
268             }
269             else if (pathInfo.length == 3) // handle /blogname/entries/entryid
270
{
271                 // return entries previous to entry specified by pathInfo
272
String JavaDoc entryid = pathInfo[2];
273                 WeblogManager wmgr = mRoller.getWeblogManager();
274                 WeblogEntryData entry = wmgr.retrieveWeblogEntry(entryid);
275                 entries = wmgr.getPreviousEntries(entry, null, mMaxEntries + 1);
276             }
277             else throw new Exception JavaDoc("ERROR: bad URL");
278             
279             // build collection
280
AtomCollection col = new AtomCollection();
281             if (entries.size() > mMaxEntries)
282             {
283                 // there are more entries, so include next link
284
WeblogEntryData lastEntry =
285                     (WeblogEntryData)entries.get(entries.size() - 1);
286                 col.setNext(createNextLink(lastEntry, start, end, offset));
287             }
288             // add up to max entries to collection
289
int count = 0;
290             Iterator JavaDoc iter = entries.iterator();
291             while (iter.hasNext() && count++ < mMaxEntries)
292             {
293                 WeblogEntryData rollerEntry = (WeblogEntryData)iter.next();
294                 AtomCollection.Member member = new AtomCollection.Member();
295                 member.setTitle(rollerEntry.getDisplayTitle());
296                 member.setUpdated(rollerEntry.getUpdateTime());
297                 member.setHref(absUrl
298                     + "/atom/" + username + "/entry/" + rollerEntry.getId());
299                 col.addMember(member);
300             }
301             return col;
302         }
303         throw new Exception JavaDoc("ERROR: not authorized");
304     }
305     
306     /**
307      * Helper method that returns collection of resources, called by getCollection().
308      */

309     public AtomCollection getCollectionOfResources(
310             String JavaDoc[] pathInfo, Date JavaDoc start, Date JavaDoc end, int offset) throws Exception JavaDoc
311     {
312         String JavaDoc username = pathInfo[0];
313         String JavaDoc absUrl = mRollerContext.getAbsoluteContextUrl(mRequest);
314         WebsiteData website = mRoller.getUserManager().getWebsite(username);
315         FileManager fmgr = mRoller.getFileManager();
316         File JavaDoc[] files = fmgr.getFiles(website);
317         if (canView(website))
318         {
319             AtomCollection col = new AtomCollection();
320             for (int i=0; i<files.length; i++)
321             {
322                 AtomCollection.Member member = new AtomCollection.Member();
323                 member.setTitle(files[i].getName());
324                 member.setUpdated(new Date JavaDoc(files[i].lastModified()));
325                 member.setHref(absUrl
326                     + "/atom/" + username + "/resource/" + files[i].getName() );
327                 col.addMember(member);
328             }
329             return col;
330         }
331         throw new Exception JavaDoc("ERROR: not authorized");
332     }
333
334     /**
335      * Helper method that returns collection of categories, called by getCollection().
336      */

337     public AtomCollection getCollectionOfCategories(
338             String JavaDoc[] pathInfo, Date JavaDoc start, Date JavaDoc end, int offset) throws Exception JavaDoc
339     {
340         String JavaDoc username = pathInfo[0];
341         String JavaDoc absUrl = mRollerContext.getAbsoluteContextUrl(mRequest);
342         WebsiteData website = mRoller.getUserManager().getWebsite(username);
343         WeblogManager wmgr = mRoller.getWeblogManager();
344         List JavaDoc items = wmgr.getWeblogCategories(website);
345         if (canView(website))
346         {
347             AtomCollection col = new AtomCollection();
348             Iterator JavaDoc iter = items.iterator();
349             Date JavaDoc now = new Date JavaDoc();
350             while (iter.hasNext())
351             {
352                 WeblogCategoryData item = (WeblogCategoryData)iter.next();
353                 AtomCollection.Member member = new AtomCollection.Member();
354                 member.setTitle(item.getPath());
355                 member.setUpdated(now);
356                 member.setHref(
357                     absUrl + "/atom/" + username + "/category/" + item.getId());
358                 col.addMember(member);
359             }
360             return col;
361         }
362         throw new Exception JavaDoc("ERROR: not authorized");
363     }
364
365     //--------------------------------------------------------------------- entries
366

367     /**
368      * Create entry in the entry collection (a Roller blog has only one).
369      */

370     public Entry postEntry(String JavaDoc[] pathInfo, Entry entry) throws Exception JavaDoc
371     {
372         // authenticated client posted a weblog entry
373
String JavaDoc username = pathInfo[0];
374         WebsiteData website = mRoller.getUserManager().getWebsite(username);
375         if (canEdit(website))
376         {
377             // Save it and commit it
378
WeblogEntryData rollerEntry = createRollerEntry(website, entry);
379             rollerEntry.save();
380             mRoller.commit();
381                         
382             // Throttle one entry per second
383
// (MySQL timestamp has 1 sec resolution, damnit)
384
Thread.sleep(1000);
385                         
386             // TODO: ping the appropriate ping
387
// TODO: flush the cache on Atom post
388
//flushPageCache(mRequest);
389

390             return createAtomEntry(rollerEntry);
391         }
392         throw new Exception JavaDoc("ERROR not authorized to edit website");
393     }
394     
395     /**
396      * Retrieve entry, URI like this /blog-name/entry/id
397      */

398     public Entry getEntry(String JavaDoc[] pathInfo) throws Exception JavaDoc
399     {
400         if (pathInfo.length == 3) // URI is /blogname/entries/entryid
401
{
402             WeblogEntryData entry =
403                 mRoller.getWeblogManager().retrieveWeblogEntry(pathInfo[2]);
404             if (!canView(entry))
405             {
406                 throw new Exception JavaDoc("ERROR not authorized to view entry");
407             }
408             else if (entry != null)
409             {
410                 return createAtomEntry(entry);
411             }
412             throw new Exception JavaDoc("ERROR: entry not found");
413         }
414         throw new Exception JavaDoc("ERROR: bad URI");
415     }
416
417     /**
418      * Update entry, URI like this /blog-name/entry/id
419      */

420     public Entry putEntry(String JavaDoc[] pathInfo, Entry entry) throws Exception JavaDoc
421     {
422         if (pathInfo.length == 3) // URI is /blogname/entries/entryid
423
{
424             WeblogEntryData rollerEntry =
425                 mRoller.getWeblogManager().retrieveWeblogEntry(pathInfo[2]);
426             if (canEdit(rollerEntry))
427             {
428                 rollerEntry.setTitle(entry.getTitle());
429                 rollerEntry.setText(((Content)entry.getContents().get(0)).getValue());
430                 rollerEntry.setUpdateTime(new Timestamp JavaDoc(new Date JavaDoc().getTime()));
431                 rollerEntry.save();
432                 mRoller.commit();
433                 return createAtomEntry(rollerEntry);
434             }
435             throw new Exception JavaDoc("ERROR not authorized to put entry");
436         }
437         throw new Exception JavaDoc("ERROR: bad URI");
438     }
439
440     /**
441      * Delete entry, URI like this /blog-name/entry/id
442      */

443     public void deleteEntry(String JavaDoc[] pathInfo) throws Exception JavaDoc
444     {
445         if (pathInfo.length == 3) // URI is /blogname/entries/entryid
446
{
447             WeblogEntryData rollerEntry =
448                 mRoller.getWeblogManager().retrieveWeblogEntry(pathInfo[2]);
449             if (canEdit(rollerEntry))
450             {
451                 rollerEntry.remove();
452                 mRoller.commit();
453                 return;
454             }
455             throw new Exception JavaDoc("ERROR not authorized to delete entry");
456         }
457         throw new Exception JavaDoc("ERROR: bad URI");
458     }
459
460     //-------------------------------------------------------------------- resources
461

462     /**
463      * Create new resource in generic collection (a Roller blog has only one).
464      * TODO: can we avoid saving temporary file?
465      * TODO: do we need to handle mutli-part MIME uploads?
466      * TODO: use Jakarta Commons File-upload?
467      */

468     public String JavaDoc postResource(String JavaDoc[] pathInfo,
469             String JavaDoc name, String JavaDoc contentType, InputStream JavaDoc is)
470             throws Exception JavaDoc
471     {
472         // authenticated client posted a weblog entry
473
String JavaDoc username = pathInfo[0];
474         WebsiteData website = mRoller.getUserManager().getWebsite(username);
475         if (canEdit(website) && pathInfo.length > 1)
476         {
477             try
478             {
479                 FileManager fmgr = mRoller.getFileManager();
480                 RollerMessages msgs = new RollerMessages();
481                 
482                 // save to temp file
483
if (name == null)
484                 {
485                     throw new Exception JavaDoc(
486                         "ERROR[postResource]: No 'name' present in HTTP headers");
487                 }
488                 File JavaDoc tempFile = File.createTempFile(name,"tmp");
489                 FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(tempFile);
490                 Utilities.copyInputToOutput(is, fos);
491                 fos.close();
492                 
493                 // If save is allowed by Roller system-wide policies
494
if (fmgr.canSave(website, name, tempFile.length(), msgs))
495                 {
496                     // Then save the file
497
FileInputStream JavaDoc fis = new FileInputStream JavaDoc(tempFile);
498                     fmgr.saveFile(website, name, tempFile.length(), fis);
499                     fis.close();
500                     
501                     // TODO: build URL to uploaded file should be done in FileManager
502
String JavaDoc uploadPath = RollerContext.getUploadPath(
503                         mRequest.getSession(true).getServletContext());
504                     uploadPath += "/" + website.getUser().getUserName() + "/" + name;
505                     return RequestUtils.printableURL(
506                         RequestUtils.absoluteURL(mRequest, uploadPath));
507                 }
508                 tempFile.delete();
509                 throw new Exception JavaDoc("File upload denied because:" + msgs.toString());
510             }
511             catch (Exception JavaDoc e)
512             {
513                 String JavaDoc msg = "ERROR in atom.postResource";
514                 mLogger.error(msg,e);
515                 throw new Exception JavaDoc(msg);
516             }
517         }
518         throw new Exception JavaDoc("ERROR not authorized to edit website");
519     }
520         
521     /**
522      * Get absolute path to resource specified by path info.
523      */

524     public String JavaDoc getResourceFilePath(String JavaDoc[] pathInfo) throws Exception JavaDoc
525     {
526         // ==> /<blogname>/resources/<filename>
527
String JavaDoc uploadPath = RollerContext.getUploadPath(
528                 mRequest.getSession(true).getServletContext());
529         return uploadPath + File.separator + pathInfo[2];
530     }
531     
532     /**
533      * Update resource specified by pathInfo using data from input stream.
534      * Expects pathInfo of form /blog-name/resources/name
535      */

536     public void putResource(String JavaDoc[] pathInfo,
537             String JavaDoc contentType, InputStream JavaDoc is) throws Exception JavaDoc
538     {
539         if (pathInfo.length > 2)
540         {
541            String JavaDoc name = pathInfo[2];
542            postResource(pathInfo, name, contentType, is);
543         }
544         throw new Exception JavaDoc("ERROR: bad pathInfo");
545     }
546
547     /**
548      * Delete resource specified by pathInfo.
549      * Expects pathInfo of form /blog-name/resources/name
550      */

551     public void deleteResource(String JavaDoc[] pathInfo) throws Exception JavaDoc
552     {
553         // authenticated client posted a weblog entry
554
String JavaDoc username = pathInfo[0];
555         WebsiteData website = mRoller.getUserManager().getWebsite(username);
556         if (canEdit(website) && pathInfo.length > 1)
557         {
558             try
559             {
560                 FileManager fmgr = mRoller.getFileManager();
561                 fmgr.deleteFile(website, pathInfo[2]);
562             }
563             catch (Exception JavaDoc e)
564             {
565                 String JavaDoc msg = "ERROR in atom.deleteResource";
566                 mLogger.error(msg,e);
567                 throw new Exception JavaDoc(msg);
568             }
569         }
570         throw new Exception JavaDoc("ERROR not authorized to edit website");
571     }
572
573     //------------------------------------------------------------------ URI testers
574

575     /**
576      * True if URL is the introspection URI.
577      */

578     public boolean isIntrospectionURI(String JavaDoc[] pathInfo)
579     {
580         if (pathInfo.length == 1 && pathInfo[0].equals(mUsername)) return true;
581         return false;
582     }
583     
584     /**
585      * True if URL is a entry URI.
586      */

587     public boolean isEntryURI(String JavaDoc[] pathInfo)
588     {
589         if (pathInfo.length > 1 && pathInfo[1].equals("entry")) return true;
590         return false;
591     }
592
593     /**
594      * True if URL is a resource URI.
595      */

596    public boolean isResourceURI(String JavaDoc[] pathInfo)
597     {
598         if (pathInfo.length > 1 && pathInfo[1].equals("resource")) return true;
599         return false;
600     }
601
602     /**
603      * True if URL is a category URI.
604      */

605     public boolean isCategoryURI(String JavaDoc[] pathInfo)
606     {
607         if (pathInfo.length > 1 && pathInfo[1].equals("category")) return true;
608         return false;
609     }
610
611     /**
612      * True if URL is a collection URI of any sort.
613      */

614     public boolean isCollectionURI(String JavaDoc[] pathInfo)
615     {
616         if (pathInfo.length > 1 && pathInfo[1].equals("entries")) return true;
617         if (pathInfo.length > 1 && pathInfo[1].equals("resources")) return true;
618         if (pathInfo.length > 1 && pathInfo[1].equals("categories")) return true;
619         return false;
620     }
621
622     /**
623      * True if URL is a entry collection URI.
624      */

625     public boolean isEntryCollectionURI(String JavaDoc[] pathInfo)
626     {
627         if (pathInfo.length > 1 && pathInfo[1].equals("entries")) return true;
628         return false;
629     }
630
631     /**
632      * True if URL is a resource collection URI.
633      */

634     public boolean isResourceCollectionURI(String JavaDoc[] pathInfo)
635     {
636         if (pathInfo.length > 1 && pathInfo[1].equals("resources")) return true;
637         return false;
638     }
639
640     /**
641      * True if URL is a category collection URI.
642      */

643     public boolean isCategoryCollectionURI(String JavaDoc[] pathInfo)
644     {
645         if (pathInfo.length > 1 && pathInfo[1].equals("categories")) return true;
646         return false;
647     }
648
649     //------------------------------------------------------------------ permissions
650

651     /**
652      * Return true if user is allowed to edit an entry.
653      */

654     private boolean canEdit(WeblogEntryData entry)
655     {
656         return entry.getWebsite().getUser().getUserName().equals(mUsername);
657     }
658     
659     /**
660      * Return true if user is allowed to edit a website.
661      */

662     private boolean canEdit(WebsiteData website)
663     {
664         return website.getUser().getUserName().equals(mUsername);
665     }
666     
667     /**
668      * Return true if user is allowed to view an entry.
669      */

670     private boolean canView(WeblogEntryData entry)
671     {
672         return canEdit(entry);
673     }
674     
675     /**
676      * Return true if user is allowed to view a website.
677      */

678     private boolean canView(WebsiteData website)
679     {
680         return canEdit(website);
681     }
682
683     //-------------------------------------------------------------- authentication
684

685     /**
686      * Perform WSSE authentication based on information in request.
687      * Will not work if Roller password encryption is turned on.
688      */

689     protected String JavaDoc authenticateWSSE(HttpServletRequest JavaDoc request)
690     {
691         String JavaDoc wsseHeader = request.getHeader("X-WSSE");
692         if (wsseHeader == null) return null;
693         
694         String JavaDoc ret = null;
695         String JavaDoc userName = null;
696         String JavaDoc created = null;
697         String JavaDoc nonce = null;
698         String JavaDoc passwordDigest = null;
699         String JavaDoc[] tokens = wsseHeader.split(",");
700         for (int i = 0; i < tokens.length; i++)
701         {
702             int index = tokens[i].indexOf('=');
703             if (index != -1)
704             {
705                 String JavaDoc key = tokens[i].substring(0, index).trim();
706                 String JavaDoc value = tokens[i].substring(index + 1).trim();
707                 value = value.replaceAll("\"", "");
708                 if (key.startsWith("UsernameToken"))
709                 {
710                     userName = value;
711                 }
712                 else if (key.equalsIgnoreCase("nonce"))
713                 {
714                     nonce = value;
715                 }
716                 else if (key.equalsIgnoreCase("passworddigest"))
717                 {
718                     passwordDigest = value;
719                 }
720                 else if (key.equalsIgnoreCase("created"))
721                 {
722                     created = value;
723                 }
724             }
725         }
726         String JavaDoc digest = null;
727         try
728         {
729             UserData user = mRoller.getUserManager().getUser(userName);
730             digest = WSSEUtilities.generateDigest(
731                         WSSEUtilities.base64Decode(nonce),
732                         created.getBytes("UTF-8"),
733                         user.getPassword().getBytes("UTF-8"));
734             if (digest.equals(passwordDigest))
735             {
736                 ret = userName;
737             }
738         }
739         catch (Exception JavaDoc e)
740         {
741             mLogger.error("ERROR in wsseAuthenticataion: " + e.getMessage(), e);
742         }
743         return ret;
744     }
745
746     /**
747      * Untested (and currently unused) implementation of BASIC authentication
748      */

749     public String JavaDoc authenticateBASIC(HttpServletRequest JavaDoc request)
750     {
751         boolean valid = false;
752         String JavaDoc userID = null;
753         String JavaDoc password = null;
754         try
755         {
756             String JavaDoc authHeader = request.getHeader("Authorization");
757             if (authHeader != null)
758             {
759                StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(authHeader);
760                if (st.hasMoreTokens())
761                {
762                   String JavaDoc basic = st.nextToken();
763                   if (basic.equalsIgnoreCase("Basic"))
764                   {
765                      String JavaDoc credentials = st.nextToken();
766                      String JavaDoc userPass = new String JavaDoc(Base64.decode(credentials));
767                      int p = userPass.indexOf(":");
768                      if (p != -1)
769                      {
770                         userID = userPass.substring(0, p);
771                         UserData user = mRoller.getUserManager().getUser(userID);
772                         String JavaDoc realpassword = LoginServlet.getEncryptedPassword(
773                             request, user.getUserName(), user.getPassword());
774                         password = userPass.substring(p+1);
775                         if ( (!userID.trim().equals(user.getUserName()))
776                              && (!password.trim().equals(realpassword)))
777                         {
778                            valid = true;
779                         }
780                      }
781                   }
782                }
783             }
784         }
785         catch (Exception JavaDoc e)
786         {
787             mLogger.debug(e);
788         }
789         if (valid) return userID;
790         return null;
791     }
792  
793     //----------------------------------------------------------- internal utilities
794

795     /**
796      * Create next member list suitable for use in entry collection.
797      * Puts state date, end date and off set in request parameters.
798      */

799     private String JavaDoc createNextLink(
800             WeblogEntryData entry, Date JavaDoc start, Date JavaDoc end, int offset)
801     {
802         SimpleDateFormat JavaDoc df = new SimpleDateFormat JavaDoc( "yyyy-MM-dd'T'HH:mm:ssZ" );
803         String JavaDoc absUrl = mRollerContext.getAbsoluteContextUrl();
804         String JavaDoc url = absUrl + "/atom/" + mUsername + "/entries/" + entry.getId();
805         if (offset != -1 && start != null && end != null)
806         {
807             url = url + "?Range=" + df.format(start) + "/" + df.format(end);
808         }
809         else if (offset != -1 && start != null)
810         {
811             url = url + "?Range=" + df.format(start) + "/";
812         }
813         else if (offset != -1 && end != null)
814         {
815             url = url + "?Range=/" + df.format(end);
816         }
817         if (offset != -1)
818         {
819             url = url + "&offset=" + (offset + mMaxEntries);
820         }
821         return url;
822     }
823     
824     /**
825      * Create a Rome Atom entry based on a Roller entry.
826      * Content is escaped.
827      * Link is stored as rel=alternate link.
828      */

829     private Entry createAtomEntry(WeblogEntryData entry)
830     {
831         Entry atomEntry = new Entry();
832         Content content = new Content();
833         content.setMode(Content.ESCAPED);
834         content.setValue(entry.getText());
835         List JavaDoc contents = new ArrayList JavaDoc();
836         contents.add(content);
837         
838         atomEntry.setId( entry.getId());
839         atomEntry.setTitle( entry.getTitle());
840         atomEntry.setContents( contents);
841         atomEntry.setIssued( entry.getPubTime());
842         atomEntry.setModified( entry.getUpdateTime());
843        
844         List JavaDoc links = new ArrayList JavaDoc();
845         Link altlink = new Link();
846         altlink.setRel("alternate");
847         altlink.setHref(entry.getPermaLink());
848         links.add(altlink);
849         atomEntry.setAlternateLinks(links);
850         
851         return atomEntry;
852     }
853     
854     /**
855      * Create a Roller weblog entry based on a Rome Atom entry object
856      */

857     private WeblogEntryData createRollerEntry(WebsiteData website, Entry entry)
858     {
859         Timestamp JavaDoc current = new Timestamp JavaDoc(System.currentTimeMillis());
860         Timestamp JavaDoc pubTime = current;
861         Timestamp JavaDoc updateTime = current;
862         if (entry.getIssued() != null)
863         {
864             pubTime = new Timestamp JavaDoc( entry.getIssued().getTime() );
865         }
866         if (entry.getModified() != null)
867         {
868             updateTime = new Timestamp JavaDoc( entry.getModified().getTime() );
869         }
870         WeblogEntryData rollerEntry = new WeblogEntryData();
871         rollerEntry.setTitle(entry.getTitle());
872         rollerEntry.setText( ((Content)entry.getContents().get(0)).getValue() );
873         rollerEntry.setPubTime(pubTime);
874         rollerEntry.setUpdateTime(updateTime);
875         rollerEntry.setWebsite(website);
876         rollerEntry.setPublishEntry( Boolean.TRUE );
877         rollerEntry.setCategory(website.getBloggerCategory());
878         
879         return rollerEntry;
880     }
881 }
882
Popular Tags