I am new to using the Dropbox API and I want to access every team member's folder permissions and put it into a database, but I'm having trouble on where to find this information. I am able to access each member's folders and can see the name of every folder, but not the permissions of each folder that the user has. How can I do this?
Here is what I have so far:
public MainPage()
{
this.InitializeComponent();
var task = Task.Run((Func<Task>)MainPage.Run);
task.Wait();
}
static async Task Run()
{
using (DropboxTeamClient DBTeamClient = new DropboxTeamClient("MY ACCESS KEY"))
{
//get all the dropbox members
var members = await DBTeamClient.Team.MembersListAsync();
//loop through all members ordered by email alphabetical
foreach (var member in members.Members.OrderBy(a => a.Profile.Email))
{
//get each user
var userClient = DBTeamClient.AsMember(member.Profile.TeamMemberId);
//get each user's file information
var list = await userClient.Files.ListFolderAsync(string.Empty);
//loop through the list of file and show permissions on folders
foreach (var item in list.Entries.OrderBy(b => b.PathDisplay))
{
//only display folder information
if (item.IsFolder)
{
//find out the user's permissions to this folder here?
//then I will output user information and permissions to a db
}
}
}
}
}
Am I approaching this the wrong way? Any guidance is appreciated, thanks in advance!
Thanks to Greg's comment and post on Dropbox I was able to solve my problem. Here is his solution:
"When you list files and folders using FilesUserRoutes.ListFolderAsync like this, you're listing the contents of the member's Dropbox folder, which will include both shared folders (where they have some specific permission level) as well as their private folders (where they don't have a specific permission level, since it's just their folders). For shared folders, the returned FolderMetadata.SharingInfo will be set, but it doesn't contain information about that user's permission level in that folder. (By the way, make sure you implement ListFolderContinueAsync as well, to make sure you can retrieve all results, when using ListFolderAsync. Check out the ListFolderAsync documentation for more information.)
Instead, if you want to list the shared folders the user has access to, including their level of access in each one, you should use SharingUserRoutes.ListFoldersAsync. Likewise, make sure you implement SharingUserRoutes.ListFoldersContinueAsync too, as this interface is also paginated. Each returned SharedFolderMetadata will list the user's AccessType and Permissions.
Here's a little example:
var actionsToCheck = new Dropbox.Api.Sharing.FolderAction[] { Dropbox.Api.Sharing.FolderAction.EditContents.Instance, Dropbox.Api.Sharing.FolderAction.InviteEditor.Instance };
var list = await userClient.Sharing.ListFoldersAsync(actions: actionsToCheck); // actions can optionally be supplied to check the permissions the user has for specific actions
foreach (var item in list.Entries)
{
Console.WriteLine(item.SharedFolderId);
Console.WriteLine(item.PathLower); // only set if the folder is mounted
Console.WriteLine(item.AccessType);
Console.WriteLine(item.Permissions);
}
// and so on, iterating over pages from userClient.Sharing.ListFoldersContinueAsync if list.Cursor is set
Hope this helps!"
I hope others find this as useful as I did.
Related
I'm starting to play around with the OneDrive API for .net, in order to get a list of all the items included within a folder i'm using the following call:
Item folder=null;
try
{
string expandValue = "thumbnails,children";
folder = await a_oneDriveDevice.Drive.Root.ItemWithPath(path)
.Request()
.Expand(expandValue)
.GetAsync();
}
catch (Exception ohno)
{
}
However i have been unable to find within the documentation what are the proper filters to add to the Expand() function to retrieve only a list of files (or folders).
Could anybody point me to the right direction?
Thanks!
Since you want the filter to apply to the children of the item you're requesting, you're correct that you will need to update the expandValue. Since the API is built around OData, your filter will actually become a sub-option on the children expansion, so something like this is what you're after:
string expandValue = "thumbnails,children(filter=folder%20ne%20null)";
I have quotas-enabled drive and I want to remove all files created by specifed user (actually a set of applications that runs using special account) from that drive. How can I do this without recursivly checking all files and folders on HDD is it created by specifed user or not? I just need to get "iterator".
Take a look on following example
[Test]
public void Test()
{
string user = #"Domain\UserName";
var files = Directory.EnumerateFiles(#"C:\TestFolder")
.Where(x => IsOwner(x, user));
Parallel.ForEach(files, File.Delete);
}
private static bool IsOwner(string filePath, string user)
{
return string.Equals(File.GetAccessControl(filePath).GetOwner(typeof (NTAccount)).Value, user,
StringComparison.OrdinalIgnoreCase);
}
In term of improving performance, I think you could use Task Parallel Library when using recursive algorithm to search file and folder.
Another way, you could do that Lucence was a useful framework for search and it was already published version for .NET
Actually, you can do that iteratively and very efficiently using USN Change Journal, see http://msdn.microsoft.com/en-us/library/windows/desktop/aa363798.aspx. With proper use of filtering, you can get list of files created by specific user within specific time period.
On the other hand, this technique is quite complicated and is suitable for time-critical applications; if efficiency is not the focal point of your application, I'd choose simpler solution.
I need to create desktop shortcuts to my app for all administratos in the system.
I'm using the following code to get user list.
var identifier = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
GroupPrincipal group = GroupPrincipal.FindByIdentity(new PrincipalContext(ContextType.Machine), identifier.Value);
foreach (Principal principal in group.Members)
{
Console.WriteLine(principal.Name);
}
I need somehow to get desktop path for each user. Could you suggest me solution? Many thanks.
You'll want to pinvoke the SHGetFolderLocation function (http://msdn.microsoft.com/en-us/library/bb762180.aspx) which allows you to pass in an access token that represents the user you're interested in.
No idea how difficult that will be though.
There are a few options that you can go with, depending on how you want to do it.
Option A:
Hard coded, but it works for default system setups
var userDirectory = Path.Combine("C:\Users\", principal.Name, "\Desktop");
Option B:
Find for the current user, then swap it out
var currentUser = Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
var newUser = currentUser.Replace("MyUser", principal.Name);
Now, option B hasn't been fully tested, but should work!
I am trying to get a file by name from TFS. I am getting all the files from a location recursively and then looping through these to find a specific file. It appears that the VersionControl.Client.Item object does not expose the filename (or foldername).
tfs.EnsureAuthenticated();
VersionControlServer vcs = versionControlServer)tfs.GetService(typeof(VersionControlServer));
var allStaticFiles = vcs.GetItems(path + "*", RecursionType.Full).Items;
foreach (var staticFile in allStaticFiles)
{
if(staticFile == ?? // need the filename)
{
}
(Assuming TFS2008.)
The type of vcs.GetItems(...).Items is Item[].
So therefore staticFile is an Item instance.
The properties of Item are all server side because details of the path will depend on the client's workspace mapping (there can be multiple workspaces including this item on the same computer for the same user).
You can use Item.ServerItem to get the filename (take the last path element)
To the path, get a Workspace instance representing your current workspace and use one of its methods to map the ServerItem to a local path (there are a few with subtly different behaviour, without more context it is not clear which is the right one).
I am creating a TFS tool that will get "changeset information" from the TFS server.
Now, I want to provide a "TFS Browser" so that the user can browse what "branch/folder" he wants to fetch information from.
I am using a TreeView control and the GetItems function to get the items' path from TFS:
private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
{
e.Node.Nodes.RemoveAt(0);
RecursionType recursion = RecursionType.OneLevel;
Item[] items = null;
// Get the latest version of the information for the items.
ItemSet itemSet = sourceControl.GetItems(e.Node.Tag.ToString(), recursion);
items = itemSet.Items;
foreach (Item item in items)
{
if (item.ServerItem == e.Node.Tag.ToString()) //Skip self
continue;
string filename = Path.GetFileName(item.ServerItem);
if (Path.GetExtension(filename) == "")
{
TreeNode node = new TreeNode(filename, new TreeNode[] { new TreeNode() });
node.Tag = item.ServerItem;
e.Node.Nodes.Add(node);
}
}
}
The code below demonstrates that after clicking the "expand" button from a node, the app will "query" the items that are below the current "branch" (e).
However, I don't want to include files to the browser. As a quick and dirty check, I am checking if the "path" has an extension and if not, assume that it is a directory and show it. All was good until I discovered that we have a folder named "v1.1".
There is a solution. I can re-invoke GetItems and check its content. According to MSDN:
If the path argument is a file,
returns a set of Items that contain
just that file. If the path is a
folder, returns a set of Items that
contain all items in that folder. If
the path contains a wildcard
character, returns a set of Items in
the specified folder that match the
wildcard.
However, each call to GetItems take roughly a second and if a folder contains multiple files, the "expansion" of the node takes forever.
So, is there a way to just get all the "folders" from TFS? Or any other idea how to check if a path is a folder or a file?
Thanks!
It seems that there is a member called .ItemType for Item. You can check against that.
One solution that I have just found is to use the GetFileTypes method to retrieve the different extensions registered on the server. Then check every "item" against these extensions like so:
if (!Extensions.Contains(Path.GetExtension(item.ServerItem).Replace(".","").ToLower()))
{
//Add Node
}
However, this is not really fool proof. What if a folder is named FOLDER.DLL?