As I understand it, the only way to control which documents an editor can create/edit/delete/publish is by choosing their start node?
In the case, say, of an intranet, there might be users who can edit 'news' documents but nothing else.
Would I then create a news 'root' node, with news items being allowable child documents.
But if I then give those users the news 'root' node as their starting point, yes, they can create news documents as planned, but surely they can also edit, unpublish (!) or even delete (!!!!!!!!!!!!!) the 'root' node which destroys everything.
My testing seems to support this.
Is there another way?
You are right in your understanding of the "start node" concept, as well as your editors being able to mess with the root node. But realistically, will they do that, just because they can?
In the past, we've used a simple true/false property on all nodes to determine whether the node can be deleted. We called it "undeletable", and set in on nodes that were extra important not to get removed by accident. It does NOT prevent users from going to that node, remove the check mark in "Undeletable?", save the node, and THEN delete it, but then it's no longer by accident.
We hooked into miscellaneous events and checked for the property - if undeletable == true on the node or any of its children, trashing/deleting/unpublishing would be cancelled.
I've made a quick update to the methods to use ContentService, but I haven't tested them. Grab'em from here: https://gist.github.com/jannikanker/b1864522fa0b86da89903f05d107518a
Related
Out-of-the-box, an Alfresco user can read a document based on:
The document's permissions
The user's role
The user's groups
Whether the user owns the document or not
Maybe some other factors I forgot?
Now, I want to add a new factor: Whether the document is currently part of a workflow.
Alfresco's permissionDefinitions.xml allows me to define permissions based on authorities such as ROLE_LOCK_OWNER etc, but it does not seem to be the right place to add permission conditions.
I guess I will have to write some Java source code, but I am not sure what classes are responsible for this, and whether there is an Alfresco way to customize them?
So, I assume you want to somehow have nodes that are attached to a workflow have different access rights? You need to think about the behavior you want in all of the UIs and protocols you are exposing (e.g. share, WebDAV, CIFS, FTP, etc.).
If you want to set a permission on a node, you can do that via JavaScript as well as Java (See http://docs.alfresco.com/5.2/references/API-JS-setPermission.html and http://docs.alfresco.com/5.2/references/dev-services-permission.html). As was mentioned in one of the comments, you can also get the number of active workflows on a node by referencing the activeWorkflows property in JavaScript (http://docs.alfresco.com/5.2/references/API-JS-ScriptNode.html) or in Java
Depending on the specifics, I might implement this in different ways, but if all you want to do is have the permission change, you could just update it at the beginning and end of your workflow with a simple javascript call. The only thing bad about that is that it doesn't take into consideration the workflow getting canceled. You could also create a policy/behavior on an aspect you attach or even have a rule or job run that updates content based on the activeWorkflows values.
If I make an edit to a Trac ticket, but someone beat me to it, this message is displayed:
Ideally, I would read this message and figure out what I can overwrite and what I should not. But, depending on this message to keep users from overwriting what was submitted is not something that we should depend on:
This may sound a little harsh, but you'll see, when you do usability tests, that there are quite a few users who simply do not read words that you put on the screen. If you pop up an error box of any sort, they simply will not read it.
Is there a better way to prevent these overwrites in Trac - e.g., if a ticket has been modified while you were modifying it, you must refresh the page, etc?
Yes, if the server would send the page modified outside and if the javascript running in your browser could merge that into your local changes. But noone has implemented it in the current trac.
As a tester, I'd like to know whether it is possible to restrict the manual creation of new objects by the user. The restriction should be done programatically in ABAP, not by removal of permissions.
Background information: we have quite complex objects which are hard to set up manually. Therefore we have implemented a wizard, which does all the condition checking etc. when creating the object. Also, if the wizard shall work, the user must have appropriate permissions to create the object.
Is it possible to remove the object type for that complex object from the list which appears when creating a new object (pressing the New button)?
As I'm only a tester for this part of our software, I can't show any existing code. I just got the feedback "It's not possible" and that's hard to believe for me at the moment. Usability really suffers, because people try to create those objects manually and can't make it work.
I also don't need a working code example, just a hint (class or method or setting) for the developer where to find a solution. I'll then insist that he implements it :-)
Update
Today, the user can click the "New" icon. Then, a dialog appears with 4 choices. 3 choices are for simple objects which he shall create like this. However, the first item in that list is for the complex object, which is impossible to create manually (why we have the wizard). I'd like to know whether it is possible to remove that item from the list programatically.
ᵺṓᵯᶏᵴ, the information you have provided is still a bit vague. However, here is an idea that may work for you.
It might not be possible to completely automate this process, but you could ask your developer to enhance the code that processes the New button, so that it would reject any attempt to bypass the wizard for the first item on the list.
Your developer can tell you if it is feasible in your case, to have the enhancement raise an error (message of type E) to stop the user from proceeding.
This would have to be combined with end-user training to tell people to avoid the New button for that item, and use the wizard instead
ᵺṓᵯᶏᵴ, it looks like a custom dialog so it should be possible to remove it the option, alternatively if it is a standard dialog in a SAP app there is always a way to restrict it, it can be as simple as disallow entry from specific transaction codes. for example the developer could set a variable at the start of the wizard and then check for that variable when creating the object, if it not there he can show a dialog "Please use the Wizard we carefully crafted for your use......" Ok maybe you wont say all of that but you get it.
So the answer to your query is yes it can be done but the approach will depend on what it is your changing custom or standard object etc,.
Later..
I know there is a way to set permissions for Branches so specific people can't read/check-out/check-in files.
But, is there a way to completely hide those folders/branches so these people can't even see them?
Btw, we're using TFS2010.
Let's say that I have $/Proj/Branch1, and I deny read permission for $/Proj/Branch1 to user A. This would make $/Proj/Branch1 and everything underneath it invisible to user A. This is because by default items don't have any permissions on them, and just inherit from their parents.
If this is your scenario then there is no more work to do other than denying Read permission to the user in question.
The exception to the rule is when there is some child item of $/Proj/Branch1 to which user A has an allow. Let's call this item $/Proj/Branch1/Child/Several/Folders/Down.txt. Because user A is allowed to read this item, he or she has to be able to see all the parent folders, all the way up to $/. In this scenario the parent folders are visible, but not their contents (other than that one file Down.txt).
So if you want the path to truly disappear for a user, they have to lack read permission on the item in question and all children of that item. As I said, in the typical case, all you have to do is set a Deny for Read permission on the root item and it will propagate all the way down.
Thanks
P.Kelly's way work unless you broke the permission inheritance. If you broke it you'll have to repeat the deny rule at each node you broke it.
You can delete the branch (and undelete it if needed), but it will be for everybody. The feature you're asking is simply not implemented in TFS (and I too miss it), so your solution will be good only for some cases.
Back-end: I have a model (User) that has_many of another model (ContactPreference).
Front-end: An interface allowing the user to reorder, add, and delete contact preferences for a particular user.
I'd like to let the user commit all their changes all at once with a single form submit. The way I'm doing this now is with allows_nested_attributes_for :contact_preferences in the User model, and naively POSTing the attributes of the edited preferences list. It works just fine except for a glaring bug: If a user deletes a contact preference, the ID simply isn't sent, and the preference doesn't get deleted from the DB.
allows_nested_attributes_for has support for deleting objects from the collection, but it requires the client to keep track of what IDs were deleted and pass a '_destroy' => 1 parameter. This is messy logic that I'd rather avoid; I just want objects deleted unless they are explicitly included in the parameters. allows_nested_attributes_for doesn't support this behavior as far as I can tell, so I'm looking to implement my own solution.
What's the most efficient (in terms of database access) way to do this kind of update? Do I delete everything and rebuild the list from scratch? Do I load the association and pick out objects that aren't explicitly included? Perhaps there's some clever ActiveRecord magic I can use?
My personal feeling is that doing this using the :destroy => 1 flag set a lot less messy than the alternative. The alternative would be loading the association on the server, comparing the incoming parameters, figuring out which records are missing, then deleting the missing ones and updating the remaining ones. That's a lot of extra logic, DB operations, and worst of all, you'll have to hand-rework the accepts_nested_attributes_for which is a non-trivial feat.
HTML give you a little trick/hack to accomplish this without JS. Add a checkbox to each record with name :destroy. Use the high-level form helpers, e.g. check_box, not check_box_tag (which requires a lot of things to get right manually), or a higher level form helper such as the simple_form gem.
If the flag is not checked, then HTML won't submit anything, and the record stays. If the flag is checked, HTML will submit the :destroy flag, and it will be deleted with the built-in server-side mechanisms out of the box.
You didn't say much about your front-end code; it sounds like you have a bunch of JS on there. You probably hide the record when the user "removes" it, you can simply add the destroy flag programmatically in that case, if you don't want to use the check box method above. This will be a lot simpler and less error prone than trying to second-guess the backend behavior.