File Owner?
![nm_santos nm_santos](https://connect.hyland.com/legacyfs/online/avatars/Blue-user-logo.png)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-30-2012 12:16 PM
I'm using a web service when accessing alfresco API to add/remove files, etc.
So, I have a web service user created for this, when using AuthenticationUtils.start() and end().
What I need to solve is, after a file is uploaded or edited, instead of appearing modified by web_service_user I want the username of the user to appear.
Can I do that? I read that there is an aspect called SET_OWNER, will that solve my problem?
The user passes it's username to my web service, so there is no problem there.
Regards,
Nuno.
- Labels:
-
Archive
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-30-2012 07:23 PM
An exception would be if you called a custom web service (Java that is deployed to the Alfresco WAR) that used "runAs" to run as the user specified (specifically, org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork). That would do it. But letting arbitrary web service *clients* set the modified by property would be a security problem.
The ownable aspect has a property called cm
![Smiley Surprised Smiley Surprised](/i/smilies/16x16_smiley-surprised.png)
Jeff
![nm_santos nm_santos](https://connect.hyland.com/legacyfs/online/avatars/Blue-user-logo.png)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-31-2012 05:20 AM
I don't think you'll be able to do this without authenticating as the user.
An exception would be if you called a custom web service (Java that is deployed to the Alfresco WAR) that used "runAs" to run as the user specified (specifically, org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork). That would do it. But letting arbitrary web service *clients* set the modified by property would be a security problem.
The ownable aspect has a property called cmwner, which is used to set the owner of a document, but that has nothing to do with the "modified by" and "created by" properties.
Jeff
Hi Jeff,
Can you elaborate on your solution?
I couldn't find that class in the Alfresco Javadoc.
In creating my web service, what are the steps necessary?
I'm not sure how to start coding it. (just the part to run as user)
Regards,
Nuno.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-31-2012 11:42 AM
package com.someco.scripts;import java.io.Serializable;import java.util.Date;import java.util.HashMap;import java.util.Map;import org.alfresco.repo.security.authentication.AuthenticationUtil;import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;import org.alfresco.service.cmr.repository.NodeRef;import org.alfresco.service.cmr.repository.NodeService;import org.alfresco.service.namespace.QName;import org.springframework.extensions.webscripts.Status;import org.springframework.extensions.webscripts.WebScriptRequest;import org.apache.log4j.Logger;import com.someco.model.SomeCoModel;import com.someco.service.RatingService;/** * This is the controller for the rating.post web script. * * @author jpotts * */public class PostRating extends org.springframework.extensions.webscripts.DeclarativeWebScript { Logger logger = Logger.getLogger(PostRating.class); private NodeService nodeService; private RatingService ratingService; @Override protected Map<String, Object> executeImpl(WebScriptRequest req, Status status) { int ratingValue = -1; String id = req.getParameter("id"); String rating = req.getParameter("rating"); String user = req.getParameter("user"); try { ratingValue = Integer.parseInt(rating); } catch (NumberFormatException nfe) { } if (id == null || rating == null || user == null) { logger.debug("ID, rating, or user not set"); status.setCode(Status.STATUS_BAD_REQUEST, "Required data has not been provided"); } else if ((ratingValue < 1) || (ratingValue > 5)) { logger.debug("Rating out of range"); status.setCode(Status.STATUS_BAD_REQUEST, "Rating value must be between 1 and 5 inclusive"); } else { logger.debug("Getting current node"); NodeRef curNode = new NodeRef("workspace://SpacesStore/" + id); if (!nodeService.exists(curNode)) { logger.debug("Node not found"); status.setCode(Status.STATUS_NOT_FOUND, "No node found for id:" + id); } else { // Refactored to use the Rating Service //create(curNode, Integer.parseInt(rating), user); ratingService.rate(curNode, Integer.parseInt(rating), user); } } logger.debug("Setting model"); Map<String, Object> model = new HashMap<String, Object>(); model.put("node", id); model.put("rating", rating); model.put("user", user); return model; } /** * * @param nodeRef * @param rating * @param user * @deprecated Use the Rating Service instead */ protected void create(final NodeRef nodeRef, final int rating, final String user) { AuthenticationUtil.runAs(new RunAsWork<String>() { @SuppressWarnings("synthetic-access") public String doWork() throws Exception { // add the aspect to this document if it needs it if (nodeService.hasAspect(nodeRef, SomeCoModel.ASPECT_SC_RATEABLE)) { logger.debug("Document already has aspect"); } else { logger.debug("Adding rateable aspect"); nodeService.addAspect(nodeRef, SomeCoModel.ASPECT_SC_RATEABLE, null); } Map<QName, Serializable> props = new HashMap<QName, Serializable>(); props.put(SomeCoModel.PROP_RATING, rating); props.put(SomeCoModel.PROP_RATER, user); nodeService.createNode( nodeRef, SomeCoModel.ASSN_SC_RATINGS, QName.createQName(SomeCoModel.NAMESPACE_SOMECO_CONTENT_MODEL, SomeCoModel.PROP_RATING.getLocalName() + new Date().getTime()), SomeCoModel.TYPE_SC_RATING, props); logger.debug("Created node"); return ""; } }, "admin"); } public void setNodeService(NodeService nodeService) { this.nodeService = nodeService; } public void setRatingService(RatingService ratingService) { this.ratingService = ratingService; }}
The create method needs to be able to create new objects even when the person calling this web script might only have read privileges. So the method wraps its work in a "runAs" and tells Alfresco to run the code as "admin". But you could put any user there.The full example lives at this Google Code project. You'll want the code from Chapter 6 that lives in the tag that matches the Alfresco version you are using. If you need a version that works with Alfresco 4, you'll have to start with the 3.4 version and make adjustments if needed.
Jeff
![nm_santos nm_santos](https://connect.hyland.com/legacyfs/online/avatars/Blue-user-logo.png)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-31-2012 12:46 PM
I comprehend the logic behind runAs.
So, let me explain my strategy:
1. My client application will interact with my web service and uploads it's username and files to the web service.
2. The web service makes changes to the data with runAs.
Does my web service needs to implement any particular interface? If I can't use SOAP, I can try with Java RMI.
I'm not sure how I can make it run on Alfresco.
Regards,
Nuno.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-31-2012 05:40 PM
The more common way people talk to Alfresco remotely is via RESTful web scripts. The Surf Web Script framework enables you to bind URLs with specific HTTP methods (GET, POST, PUT, DELETE) to controllers (written in your choice of Java or JavaScript) which then forward to views (written in FreeMarker) that render a response in a format specified by the caller (XML, JSON, HTML, RSS, etc.).
The calling app would not use SOAP or RMI but instead would use HttpClient (or something similar) to make the calls to the server.
The code I showed you earlier is an example of a Java-based controller for a web script. So you can go to the source code I referenced and see the other parts that make up a web script (descriptor, views).
Jeff
![nm_santos nm_santos](https://connect.hyland.com/legacyfs/online/avatars/Blue-user-logo.png)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-01-2012 10:45 AM
Thanks for the help.
I've already taken a look at the Java Web Scripts Samples
![Smiley Happy Smiley Happy](/i/smilies/16x16_smiley-happy.png)
My only problem now is, how will I upload the files? All the examples I saw take data from the urls and what I need in my method are bytes.
The content of my files will be XML.
Is there a way with HTTP POST maybe?
Regards,
Nuno.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-01-2012 10:55 AM
If you need to see the web script code, use svn to checkout this code:
svn co http://alfresco-developer-guide.googlecode.com/svn/tags/ch7_3.4_enterprise/client-extensions/ .
Then, navigate to config/alfresco/extension/templates/webscripts/com/someco and look at the helloworldform web script.
That code may need to be modified slightly to run on Alfresco 4.
If you need to know how to use HttpClient to post a multi-part form with a file attachment, try Google. Here is one resource, but there are many:
http://www.theserverside.com/news/1365153/HttpClient-and-FileUpload
Jeff
![nm_santos nm_santos](https://connect.hyland.com/legacyfs/online/avatars/Blue-user-logo.png)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-05-2012 05:57 AM
Thanks for your help
I've already seen the HTTP Client documentation.
On my webscript, how can I catch a POST request?
I've already seen the strategy to encapsulate XML text in a HTTP Message Body, which is exactly what I need.
In my case I would use something like this:
private static String url = "http://localhost:8080/alfresco/service/fileUpload"; HttpClient client = new HttpClient(); PostMethod postMethod = new PostMethod(url); //upload file…
And then on the script?
What strategy can I use?
I've already read the javascript upload file, but I'm still lost 😕
Regards,
Nuno.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
06-07-2012 03:35 AM
for each (field in formdata.fields) { if (field.name == "name") { model.name = field.value; } if (field.name == "file" && field.isFile) { filename = field.filename; content = field.content; mimetype = field.mimetype; }}var results = search.luceneSearch("+PATH:\"app:company_home/*\" +TYPE:\"cm:folder\" +@cm\\:name:\"Someco\"");var targetFolder = results[0];var newDoc = targetFolder.createFile(filename);newDoc.properties.content.write(content);newDoc.properties.content.mimetype = mimetype;newDoc.save();
The code iterates over the fields in the posted form and looks for the "name" and "file" fields. When it finds them, it saves them into variables. The search is used to find a folder to store the file in. The folder's "createFile" method is called to create a new document in Alfresco with the same name as the file that was uploaded. The next line writes the content, which stores the file's bytes in the document's "content" property. Then the mimetype is set and the document is saved.Because the web script is named helloworld.post.js it will respond to POSTs. The other files that make up the web script are the descriptor (helloworldform.post.desc.xml) which tells the framework which URL to match for this web script as well as a few other settings and the view (helloworldform.post.html.ftl) which, in this case, is returning HTML after the POST happens.
Jeff
![](/skins/images/03B8A94CA56FA229F89023906A8B0EC4/responsive_peak/images/icon_anonymous_message.png)