Obsolete Alfresco documentation says:
the download or preview of content are recorded as a single read
However, with Alfresco 5+ preview does not generate any audit event (I just tried).
QUESTION: How to make Alfresco log an audit event when someone previews a document on Alfresco Share? I am not too worried about thumbnails, but at least for the "Document Details" page:
Here is my audit application configuration:
audit.alfresco-access.enabled=true
audit.tagging.enabled=false
audit.filter.alfresco-access.default.enabled=true
audit.filter.alfresco-access.transaction.type=cm:folder;cm:content
audit.filter.alfresco-access.transaction.action=CREATE|READ|UPDATE CONTENT|CHECK IN|DELETE|COPY|MOVE
audit.audit-custom.enabled=true
audit.audit-custom.sub-actions.enabled=false
Your filter for actions is not set right,
Please note that you should be using ; for separating multiple possible values, not |.
So, I think you should be able to get previews and downloads audited with:
audit.filter.alfresco-access.transaction.action=CREATE;READ;UPDATE CONTENT;CHECK IN;DELETE;COPY;MOVE
Please note also that you might want to audit one extra action : READCONTENT
I just can't findAll() make return anything even though I am able to access a specific record by findByUid().
I have taken note (and tried to workaround / set up) of the typoscript solution and the record storage page bug without any success.
I am using a dummy extension code made by the extension builder in TYPO3 (current version) for your convenience. I have tested with data manually added through the TYPO3 config ui.
Any help would be much appreciated.
All the best and thanks in advance
Mario
For 99.9 % you didn't set your storagePid properly, it has to be the PID of the page where your records are stored. Effect: findAll() uses this PID to filter the records, while findByUid(uid) ignores PID (it searches by UID wherever record is stored.
Go to the main page > Templates and make sure that you included TypoScript from your new ext, then go to constant editor and set proper PID of page with your records. Clear whole cache at the end!
Also you can debug your SQL statement like in this answer, most probably at the end of statement you'll see something like AND your_table_name.pid IN (0) which definitely means that you didn't set storagePid or you didn't clear the cache.
I am trying to use this pattern to create a dynamic file name: "Debug_%property{LogUserName}.txt"
The value of %property{LogUserName} is retrieved from log4net.LogicalThreadContext.Properties["LogUserName"], which is filled when the user logs in.
In the first time, it works perfectly. The file gets named like Debug_user1.txt (for example).
If user1 disconnects, and the user2 logs in (at the same browser) a new file should be created, but it's not happening.
It seems that the LogicalThreadContext.Properties are final variables, and can't be changed at runtime.
I tried to change the FileAppender.File property, but it doesn't work too.
Resolved this problem with stuartd's tip: calling ActivateOptions().
I have a Plone website and create a menu item.
In the sharing tab I add each user that can post a topic.
How can I prevent that user1 edits posts owned by user2? Currently user1 can edit user2 posts.
Previously I try creating a group, assign each user to this group and add the group using the sharing tab, but in this way one user edit posts from another user.
Just subtract (uncheck) the 'Can edit'-permission of the sharing-tab.
The creator of an item is by default also owner, owners have edit-permission, thus users can edit their own items but not the ones of others.
Update (according to the new comment):
To inhibit the add-privilege on subfolders you'll need to break the inheritage of the Contributors-role, to which the 'Can add'-permission is assigned to.
However this seems not to be possible, yet. Quoting Martin Aspeli from his article "Understanding permissions and roles":
"Currently (until Plone 2.1, most likely), local roles can be added at a lower level in the acqusition tree, but not taken away".
So you need to look for another approach and, as Martijn already suggested, you'll most likely want to go with a custom workflow for your - assumingly folderish - contenttype and to all types that should be allowed to add in it (fortunately by default, Images and Files inherit the state of its parent, otherwise you probably have to think of a multi-chained workflow, but that's worth a new post even, or - ugly - create copies of contenttypes only to give them another workflow).
In that case, do as follows:
Create a workflow as adviced in http://developer.plone.org/content/workflow.html (I updated it lately, please let us know, if you have suggestions for improvements or contribute yourself).
Add the 'Add portal content'-permission to your workflow (in ZMI clickon your workflowname andhit the permissions-tab, select it from the dropdown).
For each state in your workflow (click on the state's name), uncheck 'Aquire permission settings', this way you break the inheritage of the Contibutors-role. Then check the 'Add portal content'-permission for each role you want to grant it, which would be at least the Owner-role in your case, and you might also Managers be able to access everything.
Update2:
Another, more challenging but IMHO much better, approach could be:
On your contenttype's inititialization (=your ct's class is called) trigger a script (f.e. with a contentrule/eventhandler/subscriber or in you ct's class-definition, itself), which looks up the inherited sharing-permissions on the parent, blocks them (__ac_local_roles_block__ = True) and reassign all roles again, but the Contributor's one, for the new born object (your folderish contenttype).
This would avoid creating a whole new workflow just to solve this case.
To do this, please read the docs (just updated, comments always welcome), to see how an event-handler is registrated:
http://developer.plone.org/components/events.html?highlight=events#example-register-an-event-handler-on-your-contenttype-s-creation
The executed python-script could contain s.th. like:
from Acquisition import aq_parent
def inhibit_parent_inherited_contributor_role(self, event):
""" Blocks local-roles on freshly created children in our
contenttype and re-assigns all its parent's local-roles but
'Contributor' to the child.
"""
# Block all inherited local-permissions, also of grand-parents:
self.__ac_local_roles_block__ = True
# Get local-roles assigned to parent and only to parent:
parent_roles = self.aq_parent.get_local_roles()
# Iterate over each assigned user and group to get their roles:
for userid, roles in parent_roles:
# Provide a list variable, to collect the new roles:
# of a group or user:
new_roles = []
# Iterate over the user's, respectively group's, roles:
for role in roles:
# Exclude 'Contributor' of new role-list:
if role != u'Contributor':
# Add all other roles to list of new roles:
new_roles.append(role)
# Finally assign new roles to the child for each found user and group:
self.manage_setLocalRoles(userid, new_roles)
Disclaimer:
I have tested this with IObjectEditedEvent, which works fine. Whereas the IObjectAddedEvent is fired four times (why?) and I wasn't able to tame that quickly, but plone.app.contentrules.handlers.py, does :) Have a closer look at it, maybe including a contentrule in the solution can be even better.
For an in-depth code-example about roles, see Andreas Jung's lovely zopyx.plone.cassandra and its computeRoleMap.py .
And I haven't looked at collective.subtractiveworkflow, yet. In case you do, please tell us about it :)
You need to restrict editing to the Owner role if you only want to have users edit their own content.
I don't know if I'm on the right track but I'm trying to let users of my web site create there own versions of pages on my web site.
Basically I'd like to make our documentation used as a starting point where they just add details and make a new page for themselves in the process.
I have a 'book' content type that I have changed with CCK and a 'client edits' content type that uses a nodereferencefromURL widget to link itself to the book node.
So simple version of what I'm saying is I have a link on my book pages that creates a node using client edits content type. I would like to put some fields on the client edits content type that take the values of some of the fields from the book page it is linked from.
I'm sure I'm missing something as I would have thought someone would have tried this before but I can't even find a hint on how to go about this.
All I really need is a point in the right direction if my current thinking is wrong.
Current thinking is that I use a php script to get the default value for a field on the new node add screen that drags the value for a field from the book I'm linking from.
I'm thinking this is the case because there is an option for default values for the field in cck manage fields that lets you put in a php value to return a default value for your field.
Am I on the right track or is there already a module or process that does what I'm talking about and I'm just too dumb to find it.
This sounds a little strange, are your client edits going to be a diff from the original node or just coppied data?
I would prehaps do it a more simple way, just have book nodes, and have different fields disaply depending on who edits it (enable the content_permissions module). That way you can use the node clone module to create the users copy.
You will need to make a module to contain your custom php code.
I ended up using rules to save information from the user and the cloned node into hidden fields.
One that saved the original node ID into a field when ever you create content of that type unless the url ends with Clone. This means that when you create the clone the original node ID is kept in the field.
That made it easy to use a views argument that took the node ID to make the clone appear along side the original when a user visits the original page.
The second rule trick was to compute a field that saved the "store name" from the profile of the user only when saving clone content.
This meant that there was a hidden field on the clone that stored the info so I could then use another views argument to restrict the view to only people with the same store name in their profile.
I am no good with PHP but I managed to find a snippet (can't remember where) that returns the store name of the current logged in user as the argument.
global $user;
profile_load_profile($user);
return $user->profile_store_name;