What’s the difference between `NSDocument`’s `isInViewingMode` and `isLocked`? - nsdocument

The documentation for isInViewingMode states:
The value of this property is true if the document is in read-only "viewing mode," that is, if the document is locked.
But that seems identical to the isLocked property, so what really is the difference between these two?

The documentation of isInViewingMode also states:
The value of this property is YES if the document is in read-only "viewing mode," that is, if the document is locked. You can use this information to prevent certain kinds of user actions or changes when the user is viewing an old document revision.
"if the document is locked" is very confusing, the document is not locked.
The documentation of isLocked states:
A Boolean value indicating whether or not the file can be written to.
This property may contain the value YES because the user lacks the appropriate write permissions, the “user immutable” flag was raised, the parent directory or volume is read only, or the checkAutosavingSafetyAndReturnError: method returned NO.
A document can be in viewing mode in the version browser or locked when writing is not allowed or neither.

Related

Xpages ACL validation from the XSP document level

Is it possible to validate the Xpage's ACL depending on the Source document's field value.
We need to make the Authors & Readers ability at XPage level (as per requirement I am not supposed to use the ROLES, since, it is dependent on each individual Authors which is stored in backend document FIELD).
Kindly suggest the approach, as I am not even looking HideWhen for the Buttons(edit,save etc)
Example code in the ACLEntry[0] in Xpage:
if getComponent("inputText1").getValue() == sessionScope.user {
session.getEffectiveUserName();
} else {
return false;
}
Thanks.
I do not quite understand your code on that property...
To query the readers/authors level at XPage level I suggest to use the database.queryAccess method (http://www-10.lotus.com/ldd/ddwiki.nsf/dx/NotesDatabase_sample_JavaScript_code_for_XPages?opendocument&comments#queryAccess)
You try to compare the username only. This may fail if your access level is computed by a membership in a group where your username is not relevant.
XPages' ACL depends on the database ACL, so you have to setup the levels there - the XPages' ACL is in addition to the "real" ACL as far as I experienced.
I also experienced that readers fields affect the ability to use an XPage to open a document by default.
I hope my answer is not too confusing ;-)
I think the question is valid (to my current knowledge):
If I want to design a workflow application but the current approver should not edit the full document I want to give him only access to parts (ie. a comment field and the approval button).
The question above relateds somehow to access controlled sections in old LN development. I so far also didn't find a good solution
What you describe is a very common workflow scenario. There are several ways how you can implement that efficiently. Here is what I would do:
Have one (or more) custom controls that render the "payload" (the fields the requester fills in)
assemble them into one bigger control that is used to render the form
compute the mode to read/edit depending on who is opening the form and the mode (new, pending approval, approved, rejected etc.)
Optional: when submitted remove submitter from the author field
Have one "Approval Control" that show only when the current user is the (current) approver and status is "pending approval" That control has fields that are NOT bound to the document, but a scope variable
The approval button triggers SSJS that takes the scope variable values and updates the document (and triggers notifications, access change etc)
The approval component can be used for any approval form. You then can contemplate not to give the approver write access since you could handle that in code.

Set document mode

I have a view on a Xpage called Main.xsp which needs to open documents in read mode on a different xpage called Contact.xsp. I get the documents to open as they should, since it's very simple and basic. But somehow the SetDocumentMode doesn't work!?
I have a button, when clicked it should set the document mode to Edit. I've tried using the simple actions from the menu, i've tried all of the examples here http://xpageswiki.com/web/youatnotes/wiki-xpages.nsf/dx/Work_with_documents_and_fields_on_the_XPage#Check+for+edit+mode+and+set+edit+mode
What the hell am i doing wrong here? Thank you in advance!
Also, even though the url is docID&action=editDocument the document is not editable.
EDIT
This is weird... I was triple-checking my ACL. And tried changing Anonymous access to Editor, and now it works!? I switch it back to Author with all the available options checked and it doesn't work!?
Is this some kind of bug?
Author rights for Anonymous does give Anonymous the ability to create a document (if that box is ticked) - but NOT the ability to EDIT any document. UNLESS you have a field of type Author that has "Anonymous" as one value (or a role that you assigned to Anonymous".
The definition of AUTHOR access:
Can create documents (if "create documents" is checked)
can edit any document where an AUTHOR field contains the user's name, a group or role (s)he is member of.
Explanation here: http://www.wissel.net/blog/d6plinks/SHWL-89PMVR
(and basics before here: http://www.wissel.net/blog/d6plinks/SHWL-89N7XR )

Storing private "octet string" in Active Directory; what is secure by default?

I am essentially storing a private key (Hash) in any of the OctetString attributes within Active Directory.
My question is, what attribute is secure by default and makes sense to keep private data there? This value should be considered similar to a password, where even administrators shouldn't have access (if possible), just like the current AD Password.
Here is a start of a list of attributes that are enabled by default on a Windows 2008R2 + Exchange 2010 domain.
Update:
Does anyone know of an Octet String attribute that does not expose "read" permissions to all users in the domain by default? I don't want to store my hash publicly and allow someone to build a rainbow table based on the hashes.
Here is the answer for the fella who upvoted my question... it's pretty interesting:
The default permissions in Active Directory are such that Authenticated Users have blanket read access to all attributes. This makes it difficult to introduce a new attribute that should be protected from being read by everyone.
To mitigate this, Windows 2003 SP1 introduces a way to mark an attribute as CONFIDENTIAL. This feature achieved by modifying the searchFlags value on the attribute in the schema. SearchFlags contains multiple bits representing various properties of an attribute. E.g. bit 1 means that the attribute is indexed. The new bit 128 (7th bit) designates the attribute as confidential.
Note: you cannot set this flag on base-schema attributes (those derived from "top" such as common-name). You can determine if an object is a base schema object by using LDP to view the object and checking the systemFlags attribute of the object. If is the 10th bit is set it is a base schema object.
When the Directory Service performs a read access check, it checks for confidential attributes. If there are, then in addition to READ_PROPERTY access, the Directory Service will also require CONTROL_ACCESS access on the attribute or its property set.
By default, only Administrators have CONTROL_ACCESS access to all objects. Thus, only Administrators will be able to read confidential attributes. Users are free to delegate this right to any specific group they want. This can be done with DSACLs tool, scripting, or the R2 ADAM version of LDP. As of this writing is not possible to use ACL UI Editor to assign these permissions.
The process of marking an attribute Confidential and adding the users that need to view the attribute has 3 Steps
1.Determining what attribute to mark Confidential, or adding an attribute to mark Confidential.
2.Marking it confidential
3.Granting the correct users the Control_Access right so they can view the attribute.
For more details and step-by-step instructions, please refer to the following article:
922836 How to mark an attribute as confidential in Windows Server 2003 Service Pack 1
http://support.microsoft.com/default.aspx?scid=kb;EN-US;922836
It doesn't actually important whether you use an attribute of OctetString syntax or somewhat else such as DirectoryString. What is important from the security point of view is the security descriptor assigned to the entry or branch of entries that hold your attributes. In other words, a binary attribute value hardly makes your system more secure, unless a proper security is assigned to the directory tree.
You cannot have security similar to unicodePwd attributes has, because it's kind of special. While you can assign a security descriptor that prohibits accessing your attribute values even by an administrator, you cannot disable administrator from changing security descriptor and ultimately acquiring the access to the value.
Unless you totally plan to lock yourself into AD I would suggest just adding an Aux class with your Octet String attribute and use that. (I.e. Not all other schema's might have the same attribute with the same syntax. Just ran into that with destinationIndicator. SunOne and eDirectory have different schema syntaxes.)
Then I would encrypt the contents of the attribute, since it is too hard to guarantee privacy of the data otherwise.

Non-deprecated code for detecting whether a SharePoint User has a specific Permission Level

In our application, we have some forms which need to show some data specifically if the current user has a specific permission level. These users belong to an SPGroup which includes users who should not see this data, so in this particular case I cannot filter based off of group membership.
My current solution has been to use web.CurrentUser.Roles and use a simple check on whether it contains a permission level of the correct name. Roles is of the deprecated SPRole class, so I am bombarded with warning messages despite the fact it technically works. It suggests that I use SPRoleAssignment or SPRoleDefinition (the recommendation seems arbitrary since some lines recommend one while others recommend the other even though it is being used for the same thing).
However, I cannot seem to find any method to directly retrieve an SPRoleAssignment or SPRoleDefinition object from an SPUser or SPPrincipal object, nor can I retrieve either object corresponding specifically to the current user of the SPWeb object.
How can I update these methods to use non-deprecated code? I've found other cases of determining user permissions, but I haven't found one that will work from a starting point of the current web or the current user. It's not urgent, but it certainly is helpful to avoid having to sift through all of those warnings just to reach the more important warnings.
On the actual object, e.g. and SPList, you can call the DoesUserHavePermission method, e.g.
someList.DoesUserHavePermissions(SPBasePermissions.ViewUsageData);

How to handle entity creation/editing in a master-detail

I'm wondering what strategies people are using to handle the creation and editing of an entity in a master-detail setup. (Our app is an internet-enabled desktop app.)
Here's how we currently handle this: a form is created in a popup for the entity that needs to be edited, which we give a copy of the object. When the user clicks the "Cancel" button, we close the window and ignore the object completely. When the user clicks the "OK" button, the master view is notified and receives the edited entity. It then copies the properties of the modified entity into the original entity using originalEntity.copyFrom(modifiedEntity). In case we want to create a new entity, we pass an empty entity to the popup which the user can then edit as if it was an existing entity. The master view needs to decide whether to "insert" or "update" the entities it receives into the collection it manages.
I have some questions and observations on the above workflow:
who should handle the creation of the copy of the entity? (master or detail)
we use copyFrom() to prevent having to replace entities in a collection which could cause references to break. Is there a better way to do this? (implementing copyFrom() can be tricky)
new entities receive an id of -1 (which the server tier/hibernate uses to differentiate between an insert or an update). This could potentially cause problems when looking up (cached) entities by id before they are saved. Should we use a temporary unique id for each new entity instead?
Can anyone share tips & tricks or experiences? Thanks!
Edit: I know there is no absolute wrong or right answer to this question, so I'm just looking for people to share thoughts and pros/cons on the way they handle master/details situations.
There are a number of ways you could alter this approach. Keep in mind that no solution can really be "wrong" per se. It all depends on the details of your situation. Here's one way to skin the cat.
who should handle the creation of the copy of the entity? (master or detail)
I see the master as an in-memory list representation of a subset of persisted entities. I would allow the master to handle any changes to its list. The list itself could be a custom collection. Use an ItemChanged event to fire a notification to the master that an item has been updated and needs to be persisted. Fire a NewItem event to notify the master of an insert.
we use copyFrom() to prevent having to replace entities in a collection which could cause references to break. Is there a better way to do this? (implementing copyFrom() can be tricky)
Instead of using copyFrom(), I would pass the existing reference to the details popup. If you're using an enumerable collection to store the master list, you can pass the object returned from list[index] to the details window. The reference itself will be altered so there's no need to use any kind of Replace method on the list. When OK is pressed, fire that ItemChanged event. You can even pass the index so it knows which object to update.
new entities receive an id of -1 (which the server tier/hibernate uses to differentiate between an insert or an update). This could potentially cause problems when looking up (cached) entities by id before they are saved. Should we use a temporary unique id for each new entity instead?
Are changes not immediately persisted? Use a Hibernate Session with the Unit of Work pattern to determine what's being inserted and what's being updated. There are more examples of Unit of Work out there. You might have to check out some blog posts by the .NET community if there's not much on the Java end. The concept is the same animal either way.
Hope this helps!
The CSLA library can help with this situation a lot.
However, if you want to self implement :
You have a master object, the master object contains a list of child objects.
The detail form can edit a child object directly. Since everything is reference types, the master object is automatically updated.
The issue is knowing that the master object is dirty, and therefore should be persisted to your database or whatnot.
CSLA handles this with an IsDirty() property. In the master object you would query each child object to see if it is dirty, and if so persist everything (as well as tracking if the master object itself is dirty)
You can also handle this is the INotifyPropertyChanged interface.
As for some of your other questions :
You want to separate your logic. The entity can handle storage of its own properties, and integrity rules for itself, but logic for how different object interact with each other should be separate. Look into patterns such as MVC or MVP.
In this case, creation of a new child object should either be in the master object, or should be in a separate business logic object that creates the child and then adds it to the parent.
For IDs, using GUIDs as the ID can save you quite a bit of problems, because then you don't have to talk to the database to determine a correct ID. You can keep a flag on the object for if it is new or not (and therefore should be inserted or updated).
Again, CSLA handles all of this for you, but does have quite a bit of overhead.
regarding undo on cancel : CSLA has n-level undo implemented, but if you are trying to do it by hand, I would either use your CopyFrom function, or refresh the object's data from the persistance layer on cancel (re-fetch).
i just implemented such a model.but not using NH, i am using my own code to persist objects in Oracle Db.
i have used the master detail concept in the same web form.
like i have master entity grid and on detail action command i open a penal just below the clicked master record row.
On Detail Add mode, i just populate an empty entity whose id were generated in negative numbers by a static field.and on Save Detail button i saved that entity in the details list of the Master Record in Asp.NET Session.
On Detail Edit,View i populated the Detail Panel with selected Detail through ajax calls using Jquery and appended that penal just below the clicked row.
On Save Button i persisted the Master Session (containing list of Details) in database.
and i worked good for me as if multiple details a master need to fill.
also if you like you can use Jquery Modal to Popup that Panel instead of appending below the row.
Hope it helps :)
Thanks,

Resources