Share specific folder in document library using SharePoint Client Object Model - c#

I'm trying to add permissions to specific folders within a document library using the SharePoint 2013 Client Object Model in C#. In effect I'm trying to reproduce the behaviour you get when you "Share" a folder via the UI. This is the code I've got so far, but its not giving the behaviour I'm after. In the code I'm trying to add a single user to the RoleAssigments collection of the folder. Note: The document library does not inherit permissions from the site level.
using (ClientContext ctx = new ClientContext(SPSiteURL))
{
ctx.AuthenticationMode = ClientAuthenticationMode.Default;
Web web = ctx.Web;
Folder AccountFolder = web.GetFolderByServerRelativeUrl("account/" + OurFolderName);
ctx.Load(AccountFolder);
ctx.ExecuteQuery();
ListItem AllFields = AccountFolder.ListItemAllFields;
ctx.Load(AllFields);
ctx.ExecuteQuery();
// Add the user to SharePoint, if they have not already been added
Principal AccountUser = ctx.Web.EnsureUser(UsersName);
ctx.Load(AccountUser);
ctx.ExecuteQuery();
var info = Utility.ResolvePrincipal(ctx, ctx.Web, AccountUser.LoginName, PrincipalType.All, PrincipalSource.All, null, false);
context.ExecuteQuery();
Principal ResolvedUser = context.Web.EnsureUser(info.Value.LoginName);
ctx.Load(ResolvedUser);
ctx.ExecuteQuery();
// Get the existing RoleAssignments collection for the folder
RoleAssignmentCollection RoleAssignments = AllFields.RoleAssignments;
// Create a new RoleDefinitionBindingCollection object
RoleDefinitionBindingCollection collRDB = new RoleDefinitionBindingCollection(ctx);
// Get the default "Contribute" role and add it to our RoleDefinitionBindingCollection
RoleDefinition ContributeRoleDef = ctx.Web.RoleDefinitions.GetByName("Contribute");
collRDB.Add(ContributeRoleDef);
// Break the Role Inheritance, but copy the parent roles and propagate our roles down
AllFields.BreakRoleInheritance(true, true);
// Add our new RoleAssigment to the RoleAssignmentCollection for the folder
RoleAssignments.Add(ResolvedUser, collRDB);
// Push our permission update back to SharePoint
ctx.ExecuteQuery();
}

The following example demonstrates how to share folder using CSOM API:
using (var ctx = new ClientContext(webUri))
{
var folder = ctx.Web.GetFolderByServerRelativeUrl("/Shared Documents/Archive");
var folderItem = folder.ListItemAllFields;
//grant Read permissions to 'Everyone' Sec Group
var everyoneSecGroup = ctx.Web.SiteUsers.GetById(4); //get Everyone security group
ShareListItem(folderItem, everyoneSecGroup, "Read");
}
where
public static void ShareListItem(ListItem listItem, Principal principal, string permissionLevelName)
{
var ctx = listItem.Context as ClientContext;
var roleDefinition = ctx.Site.RootWeb.RoleDefinitions.GetByName(permissionLevelName);
listItem.BreakRoleInheritance(true, false);
var roleBindings = new RoleDefinitionBindingCollection(ctx) { roleDefinition };
listItem.RoleAssignments.Add(principal, roleBindings);
ctx.ExecuteQuery();
}
Result

Related

Add Power Point to existing folder within SharePoint

I have some function (shown below that works as expected) that creates a SharePoint folder. For simplicity sake we can ignore the operation of creating a folder and assume the folder already exists within the SharePoint site...
I am curious as to how to open a given folder using the API and add a file to it that is a PowerPoint. The purposes of the PowerPoint is that each newly created folder will contain a template PowerPoint which can then be copy/changed by the user removing the need for the user to download the template themselves and add the PowerPoint to the folder manually.
For simplicity as mentioned earlier we can assume the folder already exists so I would just need to access it using
var sharepoint = await graphClient.Sites.GetByPath("/sites/SiteFolder", "localhost.sharepoint.com").Request().GetAsync();
Then perform a similar Add operation that is being used to create a new folder.
I know I'd either need to read the binary data from the PowerPoint and pass that to some File object or if there's a simpler way to use the direct link to the template PowerPoint and simply create a copy of it and insert it into the SharePoint folder.
public async Task<string> Sharepoint_FolderCreate(string NewFolderName, string sharepoint_folder_path = "/SomeFolderPath")
{
var item = new DriveItem
{
Name = NewFolderName.Replace("?", " ").Replace("/", " ").Replace("\\", " ").Replace("<", " ").Replace(">", " ").Replace("*", " ").Replace("\"", " ").Replace(":", " ").Replace("|", " "),
Folder = new Folder { },
AdditionalData = new Dictionary<string, object>()
{
{"#microsoft.graph.conflictBehavior","rename"}
}
};
var scopes = new[] { "https://graph.microsoft.com/.default" };
var options = new TokenCredentialOptions
{
AuthorityHost = AzureAuthorityHosts.AzurePublicCloud
};
// https://docs.microsoft.com/dotnet/api/azure.identity.clientsecretcredential
var clientSecretCredential = new ClientSecretCredential(
tenantID, clientId, clientSecret, options);
var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
var sharepoint = await graphClient.Sites.GetByPath("/sites/SiteFolder", "localhost.sharepoint.com").Request().GetAsync();
await graphClient.Sites[sharepoint.Id].Drive.Root.ItemWithPath(sharepoint_folder_path).Children.Request().AddAsync(item);
var NewFolder = await graphClient.Sites[sharepoint.Id].Drive.Root.ItemWithPath($"{sharepoint_folder_path}/{item.Name}").Request().GetAsync();
return NewFolder.WebUrl;
}

How to copy a file to a sharepoint site

I have to copy a file on a sharepoint site.
I have seen that the only authentication working is with the AuthenticationManager.
So this works:
var authManager = new AuthenticationManager();
var ctx = authManager.GetWebLoginClientContext(strHexagon);
Web web = ctx.Web;
User user = web.CurrentUser;
ctx.Load(web);
ctx.Load(user);
ctx.ExecuteQuery();
lbxInfo.Items.Add(web.Title);
lbxInfo.Items.Add(user.LoginName);
Now, after having authenticated I need to copy a file to the sharepoint site.
I have seen that there is ctx.Web.SaveFileToLocal but what if I have to copy from local to sharepoint?
Thanks
You can use the OfficeDevPnP.Core library
string str1_Url=... <--- sharepoint site
string str2_FileSource_Full= #"C:\temp\A.txt";
string str3_FileDestination_NameExt="B.txt";
string str4_TopDestination_Folder=... <--- sharepoint site title folder
string str5_TopDestination_SubFolder=... <--- folder e.g. Production
string str6_TopDestination_AllSubFolders=...<--- subfolder e.g. Test
// AuthenticationManager -> ByPasses Multi-Factor Authentication
var authManager = new AuthenticationManager();
var ctx = authManager.GetWebLoginClientContext(str1_Url);
// Web & User definitions
Web web = ctx.Web;
User user = web.CurrentUser;
FileCreationInformation newFile = new FileCreationInformation();
newFile.Content = System.IO.File.ReadAllBytes(str2_FileSource_Full);
// Rename the destination file
newFile.Url = str3_FileDestination_NameExt;
Microsoft.SharePoint.Client.List docs = web.Lists.GetByTitle(str4_TopDestination_Folder);
// Selects a Folder inside the root one
Microsoft.SharePoint.Client.Folder folder = docs.RootFolder.Folders.GetByUrl(str5_TopDestination_SubFolder);
folder.Folders.Add(str6_TopDestination_AllSubFolders);
var targetFolder = folder.Folders.GetByUrl(str6_TopDestination_AllSubFolders);
// Uploads a file to the targetFolder
newFile.Overwrite = true;
Microsoft.SharePoint.Client.File uploadFile = targetFolder.Files.Add(newFile);
// Executes query
ctx.Load(docs);
ctx.Load(uploadFile);
ctx.Load(web);
ctx.Load(user);
ctx.ExecuteQuery();

How to access Box folder shared with me using C# SDK

Someone has shared a Box.com folder with me using the link. I need to be able to use the C# SDK or REST API to download the documents from their folder.
I have tried all 3 authentication types and have attempted to access with both the C# SDK and REST API.
//SDK attempt
var findFolder = await client.SharedItemsManager.SharedItemsAsync("https://<userWhoSharedWithMe>.box.com/s/<folderHash>"); // notFound
var folder = await client.FoldersManager.GetInformationAsync(findFolder.Id);
var items = folder.ItemCollection;
//API Attempt
var client = new HttpClient
{
BaseAddress = new Uri("https://api.box.com")
};
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "<bearerToken>");
var response = await client.GetAsync("2.0/folders/<folderId>/items");
var content = await response.Content.ReadAsStringAsync();
Is there any way to programmatically download documents from a box folder that was shared with me via link?
-- Edited 06/04/2019
The folder owner and I have tried various things and it seems the API still will not allow me to see the content of the shared folder. Is there anything the folder owner needs to do to make it visible?
Based on the suggestion that I received from a Box employee, I made the following changes.
First the snippet that didn't work as expected:
// DOES NOT WORK
var reader = new StreamReader("box-config.json");
var json = reader.ReadToEnd();
var config = BoxConfig.CreateFromJsonString(json);
var sdk = new BoxJWTAuth(config);
var token = sdk.AdminToken();
var session = new OAuthSession(token, "N/A", 3600, "bearer");
boxClient = new BoxClient(config, session, asUser: boxUserId);
Secondly, the modified version that worked, allowing me to see the folder that was shared to me and allowed me to traverse its contents:
// THIS WORKS !!!!!!!!
var reader = new StreamReader("box-config.json");
var json = reader.ReadToEnd();
var config = BoxConfig.CreateFromJsonString(json);
var sdk = new BoxJWTAuth(config);
var token = sdk.UserToken(boxUserId);
boxClient = sdk.UserClient(token, boxUserId);
And for completeness' sake, here's a snippet of code that will allow you to programmatically access a Box folder and traverse its contents:
//folderId <-- You can find this ID by logging into your box account and navigating to the folder that you're interested in accessing programmatically.
var items = await boxClient.FoldersManager.GetFolderItemsAsync(folderId, limit: 5000, offset: 0, autoPaginate: false,
sort: "name", direction: BoxSortDirection.DESC);
// How many things are this folder?
Console.WriteLine($"TotalCount: {items.TotalCount}");
// Loop through those items
foreach (var item in items.Entries)
{
// Get info on each item
var file = await boxClient.FilesManager.GetInformationAsync(item.Id);
// Print the filename
Console.WriteLine($"file: {item.Name}");
}

How can I get all Active Directory Users username and display name

I have an Intranet application using ASP.Net MVC 5
I need to query all Active directory users username
I searched the net I found 2 useful post:
1- How can I get a list of users from active directory?
2- http://www.codeproject.com/Tips/599697/Get-list-of-Active-Directory-users-in-Csharp
When I query I can get the Name property but I can't get the active directory usernames
any solutions that I can get all Active directory users username?
bellow is my code:
List<TempUsers> MyTempUser = new List<TempUsers>();
var context = new PrincipalContext(ContextType.Domain, "MyDomain.com");
var searcher = new PrincipalSearcher(new UserPrincipal(context));
foreach (var result in searcher.FindAll())
{
DirectoryEntry de = result.GetUnderlyingObject() as DirectoryEntry;
MyTempUser.Add(new TempUsers { UserName = de.Properties["Name"].Value.ToString() });
}
The property name you're looking for is sAMAccountName.
Here's a list of the available attributes.
I did it this way it worked great:
1- Add reference to Active Directory services DLL
2- Add using in your controller:
using System.DirectoryServices.AccountManagement;
than I created a function to store All Active directory users in database table
bellow is the code hope help someone needs it.
public ActionResult Create()
{
List<MyADUsers> TheAllADUsers = new List<MyADUsers>();
var context = new PrincipalContext(ContextType.Domain, "MyDoman.org");
var searcher = new PrincipalSearcher(new UserPrincipal(context));
foreach (var result in searcher.FindAll())
{
TheAllADUsers.Add(new MyADUsers { ADUserName = result.SamAccountName, AD_IsMemberOf = result.UserPrincipalName, FullName = result.Name });
}
db.MyADUsersContext.AddRange(TheAllADUsers);
db.SaveChanges();
return View();
}

Connect CouchDB with asp.net C# application

How to connect couchDB with ASP.NET C# application? If any one can you give a sample application.
I had the same need and after evaluating the options available, to meet the requirements of my application, I created any components that helped me a lot and maybe they can help you and also others. I make it clear that I have no intention of promoting myself here, just sharing something that may be useful.
The detailed explanation of how to configure and use it is on Github.
Link: Nuget Package |
Github
Example of use for retrieving documents with mango-querie:
IList<User> users;
var sts = new List<String> { "ACTIVE", "LOCKED" };
using (UserRepository db = new UserRepository())
{
var query = db.FindOf("list-status", new { id = "OwnerIdloop.user.7", statuses = sts });
users = db.List<User>(query);
}
Array.ForEach(users.ToArray(), Console.WriteLine);
Example of adding documents:
User user = createUser("email#email.com");
using (UserRepository db = new UserRepository())
{
var result = db.Insert<User>(user); // add document and return instance changed with operation revision id
Console.WriteLine(result.Revision);
}
Example of changing documents:
using (UserRepository db = new UserRepository())
{
// Load document data by ID
var user = db.Get<User>("email#email.com");
user.Name = user.Name + "::CHANGED";
var result = db.Update<User>(user); // update document and return instance changed with operation revision id
Console.WriteLine(result.Revision);
}
Example of deleting documents:
using (UserRepository db = new UserRepository())
{
// Load document data by ID
var user = db.Get<User>("email#email.com");
var result = db.Delete<User>(user); // delete document from database. Return true case sucess or false case not deleted
Console.WriteLine($"Sucesso: {result}");
}
After installing the NuGet, just create an instance of MyCouch.Client and pass it the URL of your database.
using (var client = new MyCouchClient("http://127.0.0.1:5984/test"))
{
//Consume here
}
The format is: {scheme}://[{username}:{password}]/{authority}/{localpath}. From v0.11.0, there's a specific MyCouchUriBuilder that you can use for building the Uri. It will automatically e.g. apply Uri.EscapeDataString to username and password when calling SetBasicCredentials.
var uriBuilder = new MyCouchUriBuilder("http://localhost:5984/")
.SetDbName(TestConstants.TestDbName)
.SetBasicCredentials("foob#r", "p#ssword");
return new MyCouchClient(uriBuilder.Build());
For more details Click Here

Categories

Resources