Recently I have been working on a JavaScript app model project where I wanted to check the current user’s permissions within the site and on a particular list. As always I strive to use the SharePoint REST API when ever I can. So I looked at the the DoesUserHavePermissions method of the SPWeb. I used the SPRemoteAPIExplorer extension to look up this method to see what was needed to call it using REST. Version 2.0 now exposes complex types and the SP.BasePermissions type is used as an argument to this method. I wanted to check if the user had the ability to edit list items on the web. Looking at the generated ajax REST code from SPRemoteAPIExplorer I noticed it had two properties, High an Low. Since the SP.BasePermissions type is a flags type enumeration where you can combine permissions, these two properties represent the high order 32 bit integer and the low order 32 bit integer to a 64 bit integer representing the permission. The problem was how would I determine the high and low order of a given enumeration in JavaScript?
I wanted to avoid using JSOM and do everything with REST. Fortunately, I understand that you must rely on JSOM for certain things. In this case JSOM has the SP.BasePermissions type with methods for combining sets of permissions. This type is defined in SP.js. JSOM also exposes the types of permissions as a basic integer enumeration as SP.PermissionKind. This enumeration is defined in SP.Runtime.js. I still could not figure out how to get the high an low values for the permission. I knew what the values were supposed to be for the EditLisitItems permission. Looking at the permission in debug view I noticed the values were exposed by the typical nonsensical property names $4_1 and $5_1 . When ever you set the permission with a permission kind the JSOM function will bit shift the values and re-calculate the high and low values.
The final thing to note is that even though the high and low values are 32 bit integers they must be sent as strings, otherwise you will get an error stating that it could not convert the primitive value to a EDM.Int64. The SharePoint REST processor expects these a strings when converting to a 64 bit integer. Why? JavaScript does not support 64 bit integers and thus anything in a JSON payload would always be expected to be a string. This is why when dealing with entities that represent 64 bit integers the JavaScript model will typically have a High and Low property. Mozilla has an example of something similar to SP.BasePermissions with its UInt64 type js-ctypes.
An example of a successful REST call to DoesUserHavePermissions :
function getUserWebPermissionREST() {
var hostweburl = decodeURIComponent(getQueryStringParameter('SPHostUrl'));
var appweburl = decodeURIComponent(getQueryStringParameter("SPAppWebUrl"));
var restSource = appweburl + "/_api/web/doesuserhavepermissions";
//still need jsom to get high order and low order numbers of a permission
var perm = new SP.BasePermissions();
perm.set(SP.PermissionKind.editListItems);
$.ajax(
{
'url': restSource,
'method': 'POST',
'data': JSON.stringify({
'permissionMask': {
'__metadata': {
'type': 'SP.BasePermissions'
},
'High': perm.$4_1.toString(),
'Low': perm.$5_1.toString()
}
}),
'headers': {
'accept': 'application/json;odata=verbose',
'content-type': 'application/json;odata=verbose',
'X-RequestDigest': $('#__REQUESTDIGEST').val()
},
'success': function (data) {
var d = data.d.DoesUserHavePermissions;
},
'error': function (err) {
alert(JSON.stringify(err));
}
}
);
}
No matter how hard you try you still need to use JSOM
Trying to do everything using SharePoint REST is very difficult. When dealing with permissions it is much easier to leverage the built-in JSOM enumerations and SP.BasePermissions type rather than tying to replicate the same logic in your own libraries. Also if your doing app model development you will need to use the SP.AppContextSite to get the context of the host web. So when doing app model development use REST as much as possible and use common sense when to use JSOM. I hope this post helps you understand the reasoning for the SP.BasePermissions structure and its methods and why SharePoint REST uses a high and low property to represent a 64 bit integer for permissions. It would be nice if Microsoft would put actual friendly names around the $4_1 and $5_1 properties.
3 comments:
Seems the weird internal variables are due to some minification or obfuscation going on before releasing it. I have seen the names change between CU's as well. But, would be nice if they weren't, so we could hack on them in a safer way ;)
Nice find Steve, can I ask for you to put this improvement feedback into UserVoice for our product team to get visibility of this? Thanks.
Those variables $4_1 and $5_1 are temporary. They are dynamic, they change. They will be generated by Javascript and it's not a perfect solution Mik.
Post a Comment