Sergiu Dumitriu wrote:
> On 03/29/2010 06:57 PM, cjdelisle (SVN) wrote:
>> Author: cjdelisle
>> Date: 2010-03-29 18:57:58 +0200 (Mon, 29 Mar 2010)
>> New Revision: 28004
>>
>> Modified:
>>
>> platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/api/Document.java
>> platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/api/XWiki.java
>> Log:
>> XWIKI-5041: Allow script authors to load and save documents in their own
>> security context, not the user's
>
> Quick review:
>
> 1. Although this is not always the case in the current API, methods
> should not throw exceptions, since there is no way to catch them in
> Velocity, and it's not nice at all to display exceptions and stacktraces
> to the user. It would be better to catch all and return a boolean if the
> save/delete fails.
What should become of the exception?
I have seen some very old code which put the exception in the context but I
don't see that happening
anywhere in the Document or XWiki API. Is it right to eat the exception and
return false?
>
> 2. I don't quite like the comments; with an empty mind, I wouldn't
> understand what "the author of the code calling this function takes
> responsibility" actually means. Maybe something like this would be better:
>
> Save the document under the privileges of the script's author. More
> specifically, before saving, access rights are checked for the {...@link
> #getContentAuthor content author} of the context document on the target
> document, which also is set as the new author of the document.
>
> The comment for XWiki.getDocumentAsAuthor is quite good.
>
> Read below for more comments.
>
>> Modified:
>> platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/api/Document.java
>> ===================================================================
>> ---
>> platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/api/Document.java
>> 2010-03-29 16:57:48 UTC (rev 28003)
>> +++
>> platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/api/Document.java
>> 2010-03-29 16:57:58 UTC (rev 28004)
>> @@ -1823,6 +1823,64 @@
>> }
>> }
>>
>> + /**
>> + * Save the document, the author (contentAuthor) of the code calling
>> this function takes responsibility.
>> + * Saves with minorEdit set to false and no edit comment.
>> + *
>> + * @throws XWikiException if script author is not allowed to save the
>> document or if save operation fails.
>> + * @see #saveAsAuthor(String, boolean)
>
> 2.3M2 already.
Thanks, changing.
>
>> + * @since 2.3M1
>> + */
>
> public boolean saveAsAuthor()
>
>> + public void saveAsAuthor() throws XWikiException
>> + {
>> + saveAsAuthor("", false);
>> + }
>> +
>> + /**
>> + * Save the document, the author (contentAuthor) of the code calling
>> this function takes responsibility.
>> + * Saves with minorEdit set to false.
>> + *
>> + * @param comment The comment to display in document history (what did
>> you change in the document)
>> + * @throws XWikiException if script author is not allowed to save the
>> document or if save operation fails.
>> + * @see #saveAsAuthor(String, boolean)
>> + * @since 2.3M1
>> + */
>> + public void saveAsAuthor(String comment) throws XWikiException
>> + {
>> + saveAsAuthor(comment, false);
>> + }
>> +
>> + /**
>> + * Save the document, the author (contentAuthor) of the code calling
>> this function takes responsibility.
>> + * This document will be saved if the author of the document containing
>> the code which calls this function has
>> + * edit access to it. The contentAuthor of this document will be set to
>> the author of the calling script, not the
>> + * viewer.
>
> This line doesn't make sense:
I Will remove it.
>
>> + * It is unwise to allow this function to be called by the viewer of
>> the script.
>> + *
>> + * @param comment The comment to display in document history (what did
>> you change in the document)
>> + * @param minorEdit Set true to advance the document version number by
>> 0.1 or false to advance version to the next
>> + * integer + 0.1 eg: 25.1
>> + * @throws XWikiException if script author is not allowed to save the
>> document or if save operation fails.
>> + * @since 2.3M1
>> + */
>> + public void saveAsAuthor(String comment, boolean minorEdit) throws
>> XWikiException
>> + {
>
> I wonder if this is the best way to get the content author. What happens
> with all the different include methods? Specifically, DocumentA includes
> DocumentB (sheet or topic), the call is in DocumentB; what is the
> context document?
This was discussed:
"momentarily switched to the content author of the document in the context"
http://n2.nabble.com/Proposal-Add-APIs-to-get-and-save-document-in-the-security-context-of-the-author-of-the-script-which-td4791045.html
I think that we should adhere to the standard procedure that #includeInContext
and {{include context="default"}}
makes the document stay the same, this is how programmingRights work and I
don't think it is a security issue
any more than velocity is a security problem because a script coder can say
#evaluate($request.get('code'))
and allow the viewer to run code.
#includeTopic - Included document
{{include context="new" Included document
#includeInContext - Including document
#includeForm - Including document
{{include context="default" Including document
I think discussion of changing this behavior should be part of the 2.0 API
design.
>
>> + String author = getXWikiContext().getDoc().getContentAuthor();
>> + if (hasAccessLevel("edit", author)) {
>> + String viewer = getXWikiContext().getUser();
>> + try {
>> + getXWikiContext().setUser(author);
>> + saveDocument(comment, minorEdit);
>> + } finally {
>> + getXWikiContext().setUser(viewer);
>> + }
>> + } else {
>> + java.lang.Object[] args = { author, getXWikiContext().getDoc(),
>> this.doc.getFullName() };
>> + throw new XWikiException(XWikiException.MODULE_XWIKI_ACCESS,
>> XWikiException.ERROR_XWIKI_ACCESS_DENIED,
>> + "Access denied; user {0}, acting through script in document
>> {1} cannot save document {2}", null, args);
>> + }
>> + }
>> +
>> protected void saveDocument(String comment, boolean minorEdit) throws
>> XWikiException
>> {
>> XWikiDocument doc = getDoc();
>> @@ -1952,6 +2010,31 @@
>> }
>> }
>>
>> + /**
>> + * Delete the document, the author (contentAuthor) of the code calling
>> this function takes responsibility.
>> + * It is unwise to allow this function to be called by the viewer of
>> the script.
>> + *
>> + * @throws XWikiException if script author is not allowed to delete the
>> document or if save operation fails.
>> + * @since 2.3M1
>> + */
>> + public void deleteAsAuthor() throws XWikiException
>> + {
>> + String author = getXWikiContext().getDoc().getContentAuthor();
>> + if (hasAccessLevel("delete", author)) {
>> + String viewer = getXWikiContext().getUser();
>> + try {
>> + getXWikiContext().setUser(author);
>> + deleteDocument();
>> + } finally {
>> + getXWikiContext().setUser(viewer);
>> + }
>> + } else {
>> + java.lang.Object[] args = { author, getXWikiContext().getDoc(),
>> this.doc.getFullName() };
>> + throw new XWikiException(XWikiException.MODULE_XWIKI_ACCESS,
>> XWikiException.ERROR_XWIKI_ACCESS_DENIED,
>> + "Access denied; user {0}, acting through script in document
>> {1} cannot delete document {2}", null, args);
>> + }
>> + }
>> +
>> public void deleteWithProgrammingRights() throws XWikiException
>> {
>> if (hasProgrammingRights()) {
>>
>> Modified:
>> platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/api/XWiki.java
>> ===================================================================
>> ---
>> platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/api/XWiki.java
>> 2010-03-29 16:57:48 UTC (rev 28003)
>> +++
>> platform/core/trunk/xwiki-core/src/main/java/com/xpn/xwiki/api/XWiki.java
>> 2010-03-29 16:57:58 UTC (rev 28004)
>> @@ -172,6 +172,53 @@
>> }
>>
>> /**
>> + * Loads an Document from the database. Rights are checked on the
>> author (contentAuthor) of the document
>> + * containing the currently executing script before sending back the
>> loaded document.
>> + *
>> + * @param fullName the full name of the XWiki document to be loaded
>> + * @return a Document object or null if it is not accessible
>> + * @throws XWikiException
>> + * @since 2.3M1
>> + */
>> + public Document getDocumentAsAuthor(String fullName) throws
>> XWikiException
>> + {
>> + DocumentReference reference;
>> +
>
> This branching could be replaced by
> ....resolve(StringUtils.defaultString(fullName);
I copied the getDocument method and I think they ought to both be the same,
I think resolve(StringUtils.defaultString(fullName) would create confusion as to
what is actually happening and StringUtils is not currently included in
api.XWiki
which already has to many imports.
>
>> + // We ignore the passed full name if it's null to match behavior of
>> getDocument
>> + if (fullName != null) {
>> + // Note: We use the CurrentMixed Resolver since we want to use
>> the default page name if the page isn't
>> + // specified in the passed string, rather than use the current
>> document's page name.
>> + reference =
>> this.currentMixedDocumentReferenceResolver.resolve(fullName);
>> + } else {
>> + reference = this.defaultDocumentReferenceResolver.resolve("");
>> + }
>
> Perhaps you mean:
> return getDocumentAsAuthor(reference);
Thanks for pointing that out, changing...
>
>> + return getDocument(reference);
>> + }
>> +
>> + /**
>> + * Loads an Document from the database. Rights are checked on the
>> author (contentAuthor) of the document
>> + * containing the currently executing script before sending back the
>> loaded document.
>> + *
>> + * @param reference the reference of the XWiki document to be loaded
>> + * @return a Document object or null if it is not accessible
>> + * @throws XWikiException
>> + * @since 2.3M1
>> + */
>> + public Document getDocumentAsAuthor(DocumentReference reference) throws
>> XWikiException
>> + {
>> + String author = getXWikiContext().getDoc().getContentAuthor();
>> + XWikiDocument doc = this.xwiki.getDocument(reference,
>> getXWikiContext());
>> + if (this.xwiki.getRightService().hasAccessLevel("view", author,
>> doc.getFullName(),
>
> == false should be replaced by a !
Will change.
>
>> + getXWikiContext()) == false) {
>> + return null;
>> + }
>> +
>> + Document newdoc = doc.newDocument(getXWikiContext());
>> + return newdoc;
>> + }
>> +
>> + /**
>> * @param fullname the {...@link XWikiDocument#getFullName() name} of
>> the document to search for.
>> * @param lang an optional {...@link XWikiDocument#getLanguage()
>> language} to filter results.
>> * @return A list with all the deleted versions of a document in the
>> recycle bin.
>
_______________________________________________
devs mailing list
[email protected]
http://lists.xwiki.org/mailman/listinfo/devs