Get SharePoint group permissions level name based on group name Using SharePoint Rest API - rest

I am trying to get SharePoint User group permissions (Ex: Read, Contribute) based on the group name using SharePoint Rest API. My goal is to get the permission level of the group and disable features on our custom app based on the permission levels. I have tried the below url to get the group properties but couldn't get the permission level of the group. Could anyone please guide me on how to get the User group permissions.
Options Tried:
URL = http://Servename/Site/api/web/SiteGroups/getByName('group name')

You won't be able to get this from the SiteGroup object alone. Your rest-call only retrieves group information (title, id, description and other metadata). To retrieve permission levels you will need to do a couple of more calls.
See https://msdn.microsoft.com/en-us/library/office/dn531432.aspx to read more about RoleAssignment and RoleDefinition

The function below returns Group Permission Level title and rest of the information:
function init() {
clientContext = new SP.ClientContext.get_current();
oWeb = clientContext.get_web();
currentUser = oWeb.get_currentUser();
allGroups = currentUser.get_groups();
clientContext.load(allGroups);
clientContext.executeQueryAsync(OnSuccess, OnFailure);
function OnSuccess() {
var grpsEnumerator = allGroups.getEnumerator();
while (grpsEnumerator.moveNext()) {
var group = grpsEnumerator.get_current();
var grpTitle = group.get_title();
var grpid = group.get_id();
console.log('Group Id :' + grpid);
console.log('Group Title :'+ grpTitle);
roleBindings = oWeb.get_roleAssignments().getByPrincipalId(grpid).get_roleDefinitionBindings();
clientContext.load(roleBindings);
clientContext.executeQueryAsync(function () {
var iterator = roleBindings.getEnumerator();
while (iterator.moveNext()) {
current = iterator.get_current();
console.log('Show Role Defination Title : '+ current.get_name());
}
});
}
}
function OnFailure(){
console.log('Process Failed');
}
}

Related

Leverage Groups for Workflow Approvals

We're implementing a new workflow (combined with staging task sync) on an existing website where we would like to notify all members that "own" that particular section/content to approve changes.
One of the options is to have multiple roles and their corresponding workflows configured for their role and scope, but this seems like overkill - at least for us, as currently one single role is set for approvals (and another for editors)
However I've recently come across this new page property:
And have a couple of questions:
Can regular CMS users (without membership) be part of a group?
Would we be able to leverage this group for the workflow's email notifications instead of the roles? E.g. email to everyone in the owner group when a page was sent for approval.
Is this option by default inherited from the parent page when a new one is created or does it need to be set individually for each page?
We have a Kentico 11 EMS license and working on an advanced workflow, therefore custom code is possible.
Can regular CMS users (without membership) be part of a group?
- why don't you use roles here?
Would we be able to leverage this group for the workflow's email
notifications instead of the roles? E.g. email to everyone in the
owner group when a page was sent for approval.
- you'll need to customize workflow manager class, but in general yes, it is possible. You could find an inspiration in this post
Is this option by default inherited from the parent page when a new
one is created or does it need to be set individually for each page?
- Use a macro to default the field. If you populate it with anything else then the new values will be saved.
Sample code snippet for Custom Global Event Handler for Workflow steps i.e., Reject and Approve steps.
using CMS;
using CMS.Base;
using CMS.DataEngine;
using CMS.DocumentEngine;
using CMS.EmailEngine;
using CMS.EventLog;
using CMS.Helpers;
using CMS.MacroEngine;
using CMS.SiteProvider;
using CMS.WorkflowEngine;
using System;
// Registers the custom module into the system
[assembly: RegisterModule(typeof(CustomWorkflowEvent))]
public class CustomWorkflowEvent : CMSModuleLoader
{
// Module class constructor, the system registers the module under the name "CustomInit"
public CustomWorkflowEvent()
: base("CustomInit")
{
}
// Contains initialization code that is executed when the application starts
protected override void OnInit()
{
base.OnInit();
// Assigns custom handlers to events
// WorkflowEvents.Approve.After += WorkFlow_Event_After();
WorkflowEvents.Reject.After += WorkFlow_Event_After;
WorkflowEvents.Approve.After += Approve_After;
// WorkflowEvents.Action.After += WorkFlowAction_Event_After;
}
private void Approve_After(object sender, WorkflowEventArgs e)
{
try
{
WorkflowStepInfo wsi = e.PreviousStep;
if (wsi != null)
{
CMS.WorkflowEngine.Definitions.SourcePoint s = wsi.GetSourcePoint(Guid.NewGuid());
//Make sure it was an approval (standard) step
var approvers = WorkflowStepInfoProvider.GetUsersWhoCanApprove(wsi, null, SiteContext.CurrentSiteID, "UserID = " + CMSActionContext.CurrentUser.UserID, "UserID", 0, "Email, FullName, Username");
EventLogProvider.LogInformation("Approvers Data", "Approvers Data", approvers.ToString());
if (approvers != null)
{
//Loop through the approvers
string siteName = null;
SiteInfo si = SiteInfoProvider.GetSiteInfo(SiteContext.CurrentSiteID);
if (si != null)
{
siteName = si.SiteName;
}
EmailTemplateInfo eti = EmailTemplateProvider.GetEmailTemplate("Workflow.Rejected", SiteContext.CurrentSiteName);
MacroResolver mcr = MacroResolver.GetInstance();
EmailMessage message = new EmailMessage();
// Get sender from settings
message.EmailFormat = EmailFormatEnum.Both;
message.From = eti.TemplateFrom;
// Do not send the e-mail if there is no sender specified
if (message.From != "")
{
// Initialize message
// message.Recipients = strRecipientEmail;
message.Subject = eti.TemplateSubject;
// Send email via Email engine API
// EmailSender.SendEmailWithTemplateText(SiteContext.CurrentSiteName, message, eti, mcr, true);
}
}
}
}
catch (Exception ex)
{
throw;
}
}
private void WorkFlow_Event_After(object sender, WorkflowEventArgs e)
{
try
{
WorkflowStepInfo wsi = e.PreviousStep;
if (wsi != null)
{
CMS.WorkflowEngine.Definitions.SourcePoint s = wsi.GetSourcePoint(Guid.NewGuid());
//Make sure it was an approval (standard) step
var approvers = WorkflowStepInfoProvider.GetUsersWhoCanApprove(wsi, null, SiteContext.CurrentSiteID, "UserID = " + CMSActionContext.CurrentUser.UserID, "UserID", 0, "Email, FullName, Username");
EventLogProvider.LogInformation("Approvers Data", "Approvers Data", approvers.ToString());
if (approvers != null)
{
//Loop through the approvers
string siteName = null;
SiteInfo si = SiteInfoProvider.GetSiteInfo(SiteContext.CurrentSiteID);
if (si != null)
{
siteName = si.SiteName;
}
EmailTemplateInfo eti = EmailTemplateProvider.GetEmailTemplate("Workflow.Rejected", SiteContext.CurrentSiteName);
MacroResolver mcr = MacroResolver.GetInstance();
EmailMessage message = new EmailMessage();
// Get sender from settings
message.EmailFormat = EmailFormatEnum.Both;
message.From = eti.TemplateFrom;
// Do not send the e-mail if there is no sender specified
if (message.From != "")
{
// Initialize message
// message.Recipients = strRecipientEmail;
message.Subject = eti.TemplateSubject;
// Send email via Email engine API
// EmailSender.SendEmailWithTemplateText(SiteContext.CurrentSiteName, message, eti, mcr, true);
}
}
}
}
catch (Exception ex)
{
throw;
}
}
}
Hope Helps you.
Can regular CMS users (without membership) be part of a group?
It is not part of CMS users. Groups are coming from Groups Application.
GROUP: Allows you to manage user groups. Groups are a social networking
feature enabling users to find information and communicate according
to shared interests.
Would we be able to leverage this group for the workflow's email notifications instead of the roles? E.g. email to everyone in the owner group when a page was sent for approval.
No
Is this option by default inherited from the parent page when a new one is created or does it need to be set individually for each page?
No

.net core 2.0 external login - extra profile information

I have a .net core 2.0 app and am implementing external login providers like google, twitter, and facebook. I have the requirement to get the user's display name and profile picture, and can't find any documentaion of how to achieve this in .net core 2.0.
I add the authentication like this post: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/social/
Here are my twitter login and callback functions...
[HttpGet]
[Route("/api/security/login/type/socialmedia/twitter")]
public IActionResult GetTwitterLogin(string redirect_uri)
{
ClientCallback = redirect_uri;
string redirectUrl = "/api/security/login/type/socialmedia/twittercallback";
var properties = SignInManager.ConfigureExternalAuthenticationProperties("Twitter", redirectUrl);
return Challenge(properties, "Twitter");
}
[HttpGet]
[Route("/api/security/login/type/socialmedia/twittercallback")]
public async Task<HttpResponseMessage> GetTwitterCallBackAsync()
{
var info = await SignInManager.GetExternalLoginInfoAsync();
var result = await SignInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false, bypassTwoFactor: true);
if (result.Succeeded)
{
}
else
{
}
Response.StatusCode = (int)HttpStatusCode.OK;
return null;
}
It looks like you can get some items from info.Principal.Claims, but nothing for the user's display name or profile picture.
How do you get the display name or profile picture for the various login providers?
I finally figured this out...you need to add claims when you configure the authentication. These claims look at the resulting json response and pulls items from it. The pertinent lines are the ClaimActions items.
services.AddAuthentication()
.AddTwitter(twitterOptions =>
{
twitterOptions.ConsumerKey = cfg.SystemConfig["TwitterConsumerKey"];
twitterOptions.ConsumerSecret = cfg.SystemConfig["TwitterConsumerSecret"];
twitterOptions.SaveTokens = true;
twitterOptions.RetrieveUserDetails = true;
twitterOptions.ClaimActions.MapJsonKey("display-name", "name");
twitterOptions.ClaimActions.MapJsonKey("profile-image-url", "profile_image_url_https");
})
.AddFacebook(facebookOptions =>
{
facebookOptions.AppId = cfg.SystemConfig["FacebookClientId"];
facebookOptions.AppSecret = cfg.SystemConfig["FacebookClientSecret"];
facebookOptions.SaveTokens = true;
facebookOptions.ClaimActions.MapJsonKey("display-name", "name");
})
.AddGoogle(googleOptions =>
{
googleOptions.ClientId = cfg.SystemConfig["GoogleClientId"];
googleOptions.ClientSecret = cfg.SystemConfig["GoogleClientSecret"];
googleOptions.SaveTokens = true;
googleOptions.ClaimActions.MapJsonSubKey("profile-image-url", "image", "url");
googleOptions.ClaimActions.MapJsonKey("display-name", "displayName" );
});
After getting the login information in your callback using
var info = await SignInManager.GetExternalLoginInfoAsync();
If populated successfully you can query the claims and find the values
var profileImageClaim = info.Principal.Claims.Where(x => x.Type == "profile-image-url").FirstOrDefault();
Facebook images are different from google and twitter and can be found using...
var claim = info.Principal.Claims.Where(x => x.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier").FirstOrDefault();
var url = "http://graph.facebook.com/" + claim.Value + "/picture";
In ASP.NET Core 2.0, FacebookOptions uses extension methods on ClaimActions to map the profile data returned by UserInformationEndpoint.
ClaimActions.MapJsonKey(ClaimTypes.DateOfBirth, "birthday");
In the mapping above, "birthday" is a top-level property in the Facebook Graph API response that's mapped to the value represented by the claim ClaimTypes.DateOfBirth.
To grab the profile picture you would do the same thing, but since the picture in the Graph API response is a nested JSON object, you would have to use MapCustomJson()
services.AddAuthentication()
.AddFacebook(options =>
{
// ...other options omitted
options.Fields.Add("picture");
options.ClaimActions.MapCustomJson("urn:facebook:picture",
claim => (string)claim.SelectToken("picture.data.url"));
})
Here, claim is a NewtonSoft JObject that uses JPath syntax to select the nested property value and cast it to a string.
The profile picture URL will now appear in your Claims list.

Cleaning an Access Team Record in CRM

I have to clean/to empty an access team record based on an Access team template.
How can I remove all users in the access team record in one shot? or Getting the list of users and then call RemoveUserFromRecordTeamRequest() for each user?
Here is the solution:
internal void CleanAccessTeam(IVisibilityService service, Guid recordId)
{
QueryExpression query = new QueryExpression(CrmTeam.EntityLogicalName);
FilterExpression filter = new FilterExpression();
filter.Conditions.Add(new ConditionExpression(CrmTeam.Lookups.RegardingObjectId, ConditionOperator.Equal, recordId));
query.Criteria.AddFilter(filter);
var teams = service.RetrieveMultipleRecord(query);
if (teams.Entities.Count > 0)
{
service.Delete(CrmTeam.EntityLogicalName, teams.Entities[0].Id);
}
}

SharePoint O365 Get All Users With Certain Role

Is there a way to get all users who have "Full Control" permission at a site collection and subsite level and change their role to something else? PowerShell would be ideal but CSOM would be fine too if that's the only way to do it. I know I can get groups by role but I need a way to get explicitly added users.
I tried this older StackOverflow question: Get all the users based on a specific permission using CSOM in SharePoint 2013 but I keep getting a 403 forbidden error on the first ctx.ExecuteQuery(); for all sites even though I am a collection administrator. I also wonder if anyone had a PowerShell way to do it.
According the error message, I suspect that the credential is missing in your code.
Please try the code below and let me know whether it works on your side.
static void Main(string[] args)
{
var webUrl = "[your_site_url]";
var userEmailAddress = "[your_email_address]";
using (var context = new ClientContext(webUrl))
{
Console.WriteLine("input your password and click enter");
context.Credentials = new SharePointOnlineCredentials(userEmailAddress, GetPasswordFromConsoleInput());
context.Load(context.Web, w => w.Title);
context.ExecuteQuery();
Console.WriteLine("Your site title is: " + context.Web.Title);
//Retrieve site users
var users = context.LoadQuery(context.Web.SiteUsers);
context.ExecuteQuery();
foreach(var user in users)
{
Console.WriteLine(user.Email);
}
}
}
private static SecureString GetPasswordFromConsoleInput()
{
ConsoleKeyInfo info;
SecureString securePassword = new SecureString();
do
{
info = Console.ReadKey(true);
if (info.Key != ConsoleKey.Enter)
{
securePassword.AppendChar(info.KeyChar);
}
}
while (info.Key != ConsoleKey.Enter);
return securePassword;
}
}
You need the SharePoint Online Management shell to stand up a connection to O365 via Powershell.
Introduction to the SharePoint Online management shell

Function reads ALL your Facebook groups

I am listing the groups via api 2.5 using the following function:
function getMyGroups() {
FB.api('/me/groups', function(response) {
var groupList = document.getElementById('groups');
response.data.forEach(function(group) {
console.log(group);
var opt = document.createElement("option");
opt.value = group.id;
opt.innerHTML = group.name;
groupList.appendChild(opt);
});
}, {
scope: 'user_managed_groups,publish_actions'
});
}
This works perfectly, but only returns the groups created by me. there is some calls to make and return all groups that I participate?
No, the user_groups permission is gone and you can only access groups you manage since v2.4 of the Graph API.
Changelog: https://developers.facebook.com/docs/apps/changelog#v2_4