Hi,
At a customer I don't have access to a development environment, so I need to do everything OOTB. Ofcourse SharePoint isn't made to be OOTB for every customer, hence SPServices Library.
I need to build functionalitity to get all the permissions for a user on all the sites.
So what do I do?
First there is a selection on the user ($().SPServices.SPAutocomplete), this gives no problems.
Then I select a subset of sites we want to query (due to performance issue, explained later)
What I do then is get all the groups the user is part of and put it in an array. Next I get all the webs (and children => recursive) and create an html-table where the TD's have unique ID's. This also runs without any major issues.
But then, I need to get for every cell the permission of the group and web (row-column combination). This is not performant at all and makes my browser crash all the time, even for very little gets. I have even implemented the code with an interval, so that I can manage the timeouts. And it works if I put the timeout high enough, but this is so slow and takes ages to complete for big subset of sites and alot of groups.
So basically I need a matrix with permissions for a specific user (later to be implemented for ALL groups).
Does anyone have any idea where I'm going wrong? I have tested this with 0.7.2, SP2013.01 and SP2013.02. I have read a post from Paul stating something about caching (https://spservices.codeplex.com/workitem/10182), that's why I moved to SP2013.02.
Below my code.
Laurent
At a customer I don't have access to a development environment, so I need to do everything OOTB. Ofcourse SharePoint isn't made to be OOTB for every customer, hence SPServices Library.
I need to build functionalitity to get all the permissions for a user on all the sites.
So what do I do?
First there is a selection on the user ($().SPServices.SPAutocomplete), this gives no problems.
Then I select a subset of sites we want to query (due to performance issue, explained later)
What I do then is get all the groups the user is part of and put it in an array. Next I get all the webs (and children => recursive) and create an html-table where the TD's have unique ID's. This also runs without any major issues.
But then, I need to get for every cell the permission of the group and web (row-column combination). This is not performant at all and makes my browser crash all the time, even for very little gets. I have even implemented the code with an interval, so that I can manage the timeouts. And it works if I put the timeout high enough, but this is so slow and takes ages to complete for big subset of sites and alot of groups.
So basically I need a matrix with permissions for a specific user (later to be implemented for ALL groups).
Does anyone have any idea where I'm going wrong? I have tested this with 0.7.2, SP2013.01 and SP2013.02. I have read a post from Paul stating something about caching (https://spservices.codeplex.com/workitem/10182), that's why I moved to SP2013.02.
Below my code.
<h1>Rechten per gebruiker</h1>
<table cellpadding="3" cellspacing="3">
<tr>
<td><b>Gebruiker:</b></td>
<td><input type="text" title="gebruiker" id="txtGebruiker" /></td>
</tr>
<tr>
<td><b>Luik:</b></td>
<td>
<select id="ddlLuik" style="width: 155px;">
<option value="URL TO ENVIRONMENT HERE">Platform</option>
<option value="URL TO ENVIRONMENT HERE/SUB">Projectruimtes</option>
<option value="URL TO ENVIRONMENT HERE/SUB2">Opvolgsystemen</option>
<option value="URL TO ENVIRONMENT HERE/SUB3">Vergaderruimtes</option>
<option value="URL TO ENVIRONMENT HERE/SUB4">Kennisbibliotheken</option>
<option value="URL TO ENVIRONMENT HERE/SUB5">Teamsites</option>
</select>
</td>
</tr>
<tr>
<td colspan="2" align="right"><input type="button" id="btnLookup" value="Zoek rechten op" /></td>
</tr>
</table>
<input type="hidden" id="hdnUserName" />
<br/>
<div id="loader" style="display: none; width: 233px;"><div class="progress-label">Laden van permissies...</div></div>
<div id="myRACI" style="display: none;"></div>
<br/>
<div id="myRaciLegende"></div>
<script type="text/javascript" src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script type="text/javascript">
var strURL = "URL TO ENVIRONMENT HERE", objGroups = new Array(), countPerms = 0;
var progressbar = $( "#loader" ), progressLabel = $( ".progress-label" );
var intervalObj;
var timeout = 500;
progressbar.progressbar({value: false, change: function(){progressLabel.text( progressbar.progressbar( "value" ) + "%" );}});
$(document).ready(function() {
$("head").append("<link rel='stylesheet' type='text/css' href='http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css' />");
$("head").append("<style>.ui-progressbar {position: relative;} .progress-label {position: absolute;left: 50%;top: 4px;font-weight: bold;text-shadow: 1px 1px 0 #fff;color: #0070BA;}</style>");
$().SPServices.SPAutocomplete({
WebURL: strURL,
sourceList: "Lijst met gebruikersgegevens",
sourceColumn: "ImnName",
columnName: "gebruiker",
CAMLQuery: "<IsNotNull><FieldRef Name='EMail' /></IsNotNull>",
numChars: 1,
ignoreCase: true,
highlightClass: "ms-bold",
slideDownSpeed: 100,
debug: true
});
// Build the RACI legend
$().SPServices({
operation: "GetRolesAndPermissionsForSite",
webURL: strURL,
async: false,
cacheXML: false,
completefunc: function(xData, Status) {
$("#myRaciLegende").html(processRACILegende(xData.responseXML));
}
});
});
$("#btnLookup").bind("click", function(){
if($("#txtGebruiker").val() == ""){
$("#txtGebruiker").attr("style", "border: 1px solid red;");
$("#loader").hide();
return;
}
else{$("#txtGebruiker").attr("style", "border: 1px solid #A4A4A4;");}
objGroups.clear();$("#loader").show();$("#myRACI").hide();$("#hdnUserName").val("");progressbar.progressbar( "value", 0);
$().SPServices({
operation: "GetListItems",
webURL: strURL,
listName: "Lijst met gebruikersgegevens",
async: false,
cacheXML: false,
CAMLViewFields: "<ViewFields><FieldRef Name='UserName' /></ViewFields>",
CAMLQuery: "<Query><Where><Eq><FieldRef Name='ImnName' /><Value Type='Text'>" + $("#txtGebruiker").val() + "</Value></Eq></Where></Query>",
completefunc: function(xData, Status) {
if(Status == "success"){
$(xData.responseXML).filterNode("z:row").each(function() {
$("#hdnUserName").val("alfa\\" + $(this).attr("ows_UserName"));
});
}
}
});
if($("#hdnUserName").val() != "alfa\\undefined" && $("#hdnUserName").val() != ""){
// Build matrix
$().SPServices({
operation: "GetWebCollection",
webURL: $("#ddlLuik").val(),
async: false,
cacheXML: false,
completefunc: function(xData, Status) {
$("#myRACI").html(processWebsXmlSitesRACI(xData.responseXML));
}
});
countPerms = $(".webPerm").length;
if(countPerms <= 5) timeout = 100;
if(countPerms > 5 && countPerms <= 10) timeout = 150;
if(countPerms > 10 && countPerms <= 20) timeout = 350;
if(countPerms > 20 && countPerms <= 30) timeout = 500;
intervalObj = setInterval(getWebPerms, timeout);
}
else{$("#myRACI").html("<span style='color: red;'>Deze gebruiker kon niet worden gevonden.</span>");$("#myRaciLegende").hide();}
});
$("#txtGebruiker").bind("keydown", function(){$("#txtGebruiker").attr("style", "border: 1px solid #A4A4A4;");});
$.fn.filterNode = function(name){return this.find('*').filter(function(){return this.nodeName === name;});};
Array.prototype.clear = function(){while (this.length > 0) {this.pop();}};
function getWebPerms(){
var k = 0;
progressbar.progressbar( "value", Math.round(((countPerms - $(".webPerm").length) / countPerms) * 100));
obj = $(".webPerm").first();
var url = $(obj).attr("id").substring(0, $(obj).attr("id").lastIndexOf('_')), gId = $(obj).attr("id").substring($(obj).attr("id").lastIndexOf('_') + 1);
$(obj).removeClass("webPerm").html("").SPServices({
operation: "GetRoleCollectionFromGroup",
webURL: url,
groupName: objGroups[gId],
async: false,
cacheXML: false,
completefunc: function (xData, Status) {
if(Status== "success"){
strPerms = "",strTypes = "";
$(xData.responseXML).filterNode("Role").each(function(){
strName = "";strTempName = $(this).attr("Name").split(' ');
for(i = 0; i < strTempName.length; i++){strName += strTempName[i].substring(0, 1).toUpperCase();}
strPerms += strName + ", ";strTypes += $(this).attr("Name") + ", ";
});
$(obj).append("<span title='" + strTypes.substring(0, strTypes.length - 2) + "'>" + strPerms.substring(0, strPerms.length - 2) + "</span>");
}
}
});
if($(".webPerm").length < 1){$("#loader").hide();$("#myRACI").show();clearInterval(intervalObj);}
}
function processWebsXmlSitesRACI(objDoc){
function processWebs(m_objNode, m_intIndex){
strOutput += "<tr>";
strOutput += "<td class='nodot' style='padding-left:" + (m_intIndex * 20) + "px; padding-right:" + (m_intIndex * 20) + "px;'><a href='" + $(m_objNode).attr("Url") + "'>" + $(m_objNode).attr("Title") + "</a></td>";
for(j = 0; j < objGroups.length; j++){
strOutput += "<td id='" + $(m_objNode).attr("Url") + "_" + j + "' class='webPerm'></td>";
}
strOutput += "</tr>";
$().SPServices({
operation: "GetWebCollection",
webURL: $(m_objNode).attr("Url"),
async: false,
cacheXML: false,
completefunc: function(xData, Status) {
$(xData.responseXML).filterNode("Web").each(function(){processWebs(this, (m_intIndex + 1));});
}
});
}
strOutput = "";
if($(objDoc).filterNode("Web").length > 0){
strOutput += "<table class='raci'><tr><th>Site</th>";
$().SPServices({
operation: "GetGroupCollectionFromUser",
userLoginName: $("#hdnUserName").val(),
async: false,
cacheXML: false,
completefunc: function(xData, Status) {
$(xData.responseXML).filterNode("Group").each(function(){
objGroups.push($(this).attr("Name"));
strOutput += " <th><a href='/sites/dewi/_layouts/people.aspx?MembershipGroupId=" + $(this).attr("ID") + "' target='_blank'>" + $(this).attr("Name") + "</a></th>";
});
}
});
//strOutput += "<th>Site</th></tr>";
strOutput += "</tr>";
$(objDoc).filterNode("Web").each(function(){processWebs(this, 1);});
strOutput += "</table>";
}
return (strOutput);
}
function processRACILegende(objDoc){
strOutput = "<table class='raciLegende'><tr><th colspan='3' style='text-align: left;'>Legende</th></tr>";
var sorted = $(objDoc).filterNode("Role").sort( function(a,b){var at = $(a).attr('Name'), bt = $(b).attr('Name');return (at < bt) ? -1 : 1;});
$(sorted).each(function(){
strName = "";strTempName = $(this).attr("Name").split(' ');
for(i = 0; i < strTempName.length; i++){
strName += strTempName[i].substring(0, 1).toUpperCase();
}
strOutput += "<tr><td><b>" + strName + "</b></td><td>" + $(this).attr("Name") + "</td><td>" + $(this).attr("Description") + "</td></tr>";
});
strOutput += "</table>";
return (strOutput);
}
</script>
Kind regards,Laurent