JIRA grant permission to view users - c#

Is it possible to grant a role the ability to view/get the users list? I ask this because I am working on a C# application that lets developpers automatically create JIRA issues (using the SOAP api) from within the program, and I'd like to be able to let them select the assignee from a dropdown list. However, the account I connect to JIRA with needs to be an administrator, and I do not want to have an administrator account's credentials in plain text inside the codebase, since it is open to everyone.
This is what I am doing:
JiraSoapServiceClient jira = new JiraSoapServiceClient();
string token = jira.login("non_admin_account", "password");
...
//This call throws an exception saying the account needs administrative rights
var projectRoleActors = jira.getProjectRoleActors(token, projectRole,
jira.getProjectByKey(token, "EX"));
If I could give "non_admin_account" some kind of permission to grab the users list that would be perfect.. but I'm not sure that's possible.
Any solutions?

Give your use Project Administration permission instead of JIRA administration. See the method hasProjectRolePermission in DefaultProjectRoleService

One solution to your question might be to create two users, one with project admin permissions, and another as a normal user:
Use the admin user to get the list of users - create a CLI program, or use the remote SOAP C# program to get the list of users and store them in a text file. Make sure that the program isn't visible to the other users (for example, put it on your Jira server). You can either run this using the cron/scheduler every 5 minutes or run it trough the other program.
Use the other account for everything else in your C# program, let it read the list of users from the first program.

Related

Cannot Query Users' OneDrive For Business Files As The Global Administrator using Microsoft Graph

Logged in and authenticated as the Global Admin in O365 Enterprise subscription, I can query all users using Microsoft Graph. I can also query individual users with the User.Id.
But when I try to query the OneDrive files (DriveItem) for any user then I get an empty response and resource not found error. Same error when I use UserPrincipalName instead of Id.
sample request:
/v1.0/users/427d0a15-69db-4ab1-b7ae-542776ef53ed/drive/items
What is the call pattern for a Global Admin to query the drives/drive items of all users in the tenant?
I provided Admin Consent to the application already for these permissions:
public static string[] Scopes = {
"Files.ReadWrite.All",
"Sites.Read.All",
"Sites.ReadWrite.All",
"Sites.FullControl.All",
"User.ReadWrite.All",
"Directory.ReadWrite.All",
"Directory.AccessAsUser.All"
};
I am using Delegated Permissions and requesting permissions at runtime via the code using PublicClientApplication class if that matters.
Update:
I get the same "Resource Not Found" error when I call:
/v1.0/users/427d0a15-69db-4ab1-b7ae-542776ef53ed/drive/root/children
Source code:
IGraphServiceUsersCollectionPage usersCollection =
await graphClient.Users.Request().GetAsync();
foreach (User user in usersCollection)
{
IDriveItemChildrenCollectionPage childrenCollection =
await graphClient.Users[user.Id].Drive.Root.Children.Request().GetAsync();
}
When the Foreach loop iterates first time, the first user is the logged in Global Admin and the call to Drive.Root.Children works correctly, but on consequent iterations for other users, an exception is thrown with error message:
{"Code: itemNotFound\r\nMessage: The resource could not be found.\r\n\r\nInner error\r\n"}
You cannot call [/drive/items][1] directly. You need to either provide a DriveItem.Id (i.e. /drive/items/{id}) or a path (i.e. /drive/root/children).
Try this instead:
/v1.0/users/427d0a15-69db-4ab1-b7ae-542776ef53ed/drive/root/children
After days of trial and error I found out a workaround to the problem which I will post as an answer to help people having similar issues. If a better solution is provided I will accept that answer, so the hunt is still on..
It turns out that the Global O365 Admin does not by default have access to view OneDrive Business folders and files of other users in the tenant.
What I had to do is:
Login as the Global Admin to O365 portal
Go to Admin Center > Users
For each User, expand OneDrive Settings and click on "Access files"
This gives permissions to manage that user's OneDrive.
After doing this:
/v1.0/users/427d0a15-69db-4ab1-b7ae-542776ef53ed/drive/root/children
returns properly all children of that users drive items!
I said I will accept a better answer, so to define better:
An answer that shows how to do this by code
Or an answer that at least shows how to do this with less clicks. Imagine if the tenant has 100K users, the global admin has to click that Access Files button for 100K users one by one! (no bulk settings option available) That s not a great experience and not a practical solution.
Best answer would be: 1 + 2 :)
UPDATE:
I found a better workaround, that is if I set the permissions in App Mod, as opposed to Delegated permissions/User Mod. Then the app has access to all users' drives/files in One Drive and there is no need for the global admin to provide himself the permissions as such. The enterprise admin would just need to give consent to the app only once in its lifetime in the enterprise tenant. With this update I will accept this answer.

In which role should an Exchange 2013 user should be to be able to bind to someone elses inbox items?

I'm writing a .NET application using EWS Managed API to access an Exchange 2013 SP1 server. Right now I have the following issue: I have an user which is able to search successfully through mailboxes but that user is not able to retrieve an item (email) based on a given ID resulted from the search.
So, I perform the search using ServiceResponseCollection<SearchMailboxesResponse> responseCollection = service.SearchMailboxes(searchMailboxesParameters); without any issue but if I take an unique ID from the result and try to retrieve that item using the following piece of code:
ItemId itemId = new ItemId(itemIdentifier);
Item exchangeItem = Item.Bind(exchangeService, itemId);
I get the following exception:
Access is denied. Check credentials and try again.
So, I'm thinking that similar to the mailbox search capability given by a special role, the capability of reading emails from other users can be given by a special role which I don't know right now.
On the other hand, if I'm manually assigning the user that reads to the mailbox of the user that is "read", the process works fine but this cannot be done because we're speaking about thousands of users and an unknown number of administrators.
Thank you very much for your thoughts.
There is no role (apart from impersonation) to do that your trying to assert a Mailbox access right which will need to be granted to the account via Add-MailboxPermission or Add-MailboxFolderPermission or Delegate access (this will ensure the access will be audited). The other option would be to give that account your using Application Impersonation rights and use impersonation https://msdn.microsoft.com/en-us/library/office/dd633680(v=exchg.80).aspx .

C# GMAIL API Service Account Modify - unauthorized_client

I am just starting out with the c# Google.Apis.Gmail.V1 classes and using a service account to read a mailbox.
My code works fine when I use the following snippet
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(ServiceAccountEmailAddress)
{
User = "abc#test.domain.com",
Scopes = new[] { "https://www.googleapis.com/auth/gmail.readonly" }
}.FromCertificate(certificate));
With that code I can call the following successfully
if (credential.RequestAccessTokenAsync(CancellationToken.None).Result)
{
}
But I need to modify the email messages so I changed the scope from
https://www.googleapis.com/auth/gmail.readonly
to
https://www.googleapis.com/auth/gmail.modify
I now get an exception when requesting the access token
{"Error:\"unauthorized_client\", Description:\"Unauthorized client or scope in request.\", Uri:\"\""}
I have checked the service account (*.iam.gserviceaccount.com) in the Google Developers Console and I have tried all options for permissions including OWNER which should give me Full access to all resources but no joy.
I think I am just missing a simple step but I am unsure of where to look next.
TL;DR
I would read through this, but here is the short version. I know this is an older post, but hopefully it finds you!
If you have not updated/white-listed the service account's privileges/scopes in the Google Admin Console you will need to do that, make sure the domain has API access enabled, make sure the service account is setup properly, when creating the "certificate" object be aware its parameters so that it is being instantiated correctly, check the permissions on the account being impersonated and finally make sure you've made an appropriate Google Apps service account key (could have easily made an inappropriate key type.)
White-listing Google APIs in the Admin Console
This gives the Google Apps service account the abilityto use whatever scopes you provide in your Google Apps domain.
Login to the Google Apps Admin Console by using the following link.
https://admin.google.com/
The Google Apps user account must have sufficient privileges to modify domain related settings. It does not have to be the account used to create the Google Apps project in the developer console. If the account does not have privilege you will be directed to a completely different screen with no options to click on varying domain controlling web apps like "Security", "Roles", "Support", "Groups" and etc. Instead you'll dumped onto a page that shows things like "Gmail", "Drive", "Docs" and etc. that is typical user apps. The current link it drops you at is https://apps.google.com/user/hub
Click “Security.”
Click “Show more” option at the bottom of the security options list.
Click “Advanced Settings” to get the more options.
Select the “Manage API client access” link.
Now certain API scopes must be white-listed for the desired service account. In the “Client Name” text box provide the service account’s client ID. The client ID is obtained in the developer console. In the “One or more API scopes” add the desired scopes; comma delimited.
Note, if there are existing scopes they will be removed so be sure to re-add any that will be needed.
Enable Domain Wide API Access
Login to the Google Apps Admin Console by using the following link.
https://admin.google.com/
Go to the “Security” page.
Under “API reference” section
Make sure that “Enable API access” is enabled.
Creating an Appropriate Google Apps Service Account Key (Probably this)
Go to the Google Developer Console. Login as the Google Apps user that created the Google Apps project/service account. https://console.developers.google.com/
Navigate to the particular project with which you created the service account.
Click the "Service Account" button on the left of the project's page to bring up a page with all of the project's service accounts.
Click the vertical ellipse widget all the way to the right of the desired service account's row. Select “Create Key.”
Select .p12 key as it looks like this is what you're trying to use. Click "Create." Be sure to protect this key.
I have found that if the key is not created this way then it leaves open the possiblity for making either an API key or an OAuth 2.0 client/user key. These are the wrong types of keys to use in this case you would need to have created a service account key. The way outlined above forces you to create a service account key.
Modifying the Existing Google Apps Service Account's Settings
I'm not going over how to setup the actual service account, one thing you may need in your case is to make sure that the service account has domain wide delegation enabled. This is toggled in the Google Developer Console. Should be pretty easy to find.
Code
You do not provide your entire code base for creating the token, so just want to add a few things you might be doing improperly.
Make sure when you create the certificate that the secret you provide is the default "notasecret" string. This secret is currently the default value provided by all keys distributed by Google and is immutable during key creation. I had a link to prove this, but have since lost it.
X509Certificate2 certificate = new X509Certificate2(certificateFilePath, "notasecret", X509KeyStorageFlags.Exportable);
Just trying to advocate proper coding. While I have found some bugs in the past with Google's constant values that required additional string manipulation (adding additional slashes.) You should really be using the string constants that they provide in place of literals. I only say to use these because it provides a layer of abstraction, who is to say Google will never change the literal; unlikely.
In your case the new scope is:
GmailService.Scope.GmailModify
While the old scope was:
GmailService.Scope.GmailReadonly
Otherwise, everything code wise looks good to me.
Another thing to try would be to make sure that the actual Google Apps user account being impersonated by the service account has sufficient privileges. I would suspect a different error if this were the case, would be getting a 403 in the response instead. Anyway, in your case this is the "abc#test.domain.com" account. Once again you would go to the Google Admin Console, check its roles make sure it has sufficient roles checked for whatever it is you're trying to do. I don't know what specifically you'll need in this case, best bet would be to give it the same permissions as the "Super Admin" role then remove permissions as you go to see what it might actually need. Otherwise, if possible just give it "Super Admin."
If I was a gambler I would put my money on an inappropriately created service account key. I just recently ran into this and it was the only thing that produced the same exact error you're receiving. Other things would get me the same "Description" value in the response token, but not the same "Error" value. I'm not really even sure how the culprit key was made, because I didn't make it. I just know the fix was to recreate a new key with the steps above and that fixed the issue.

Make Changes to a TFS Work Item as a specific user

I am working on creating a Web application, which the users in my team will use to
make changes to TFS Work Items. I am using TFS API for this..
In order to access the TFS Server , I used my credentials within the Web Application.
Now each time someone uses the application and makes changes to TFS work items, it shows
as if I have made changes to these items since my credentials are being used in the application.
Is there a way I can use the credentials of the person logging into my application to show up on TFS as the person making the changes ?
You need to use the 'make requests on behalf of others' functionality. You can impersonate another user by following:
public void Impersonation(Uri serverUri,string userToImpersonate)
{
// Read out the identity of the user we want to impersonate
TeamFoundationIdentity identity = ims.ReadIdentity(IdentitySearchFactor.AccountName,
userToImpersonate,
MembershipQuery.None,
ReadIdentityOptions.None);
tfs_impersonated = new TfsTeamProjectCollection(serverUri, identity.Descriptor);
GetAuthenticatedIdentity(tfs_impersonated);
// Use this tfs_impersonated object to communicate to TFS as the other users.
}
And make sure your account running the website has the permission to "make requests on behalf of others":
http://www.codeproject.com/Articles/104019/TFS-API-Part-TFS-Impersonation

Log AD users in

I have a login form written in C# and I want only AD users to be able to login.
How should I do this?
string UserName = "";
string Pass = "";
Although it is not an ASP.Net app the active directory membership provider will work just fine.
Here is info on how to use this library:
http://msdn.microsoft.com/en-us/library/system.web.security.activedirectorymembershipprovider.aspx
and here is some more information:
http://msdn.microsoft.com/en-us/library/ff650308.aspx
I am sure that this is not a best practice, but, depending on your security needs, you could allow all domain users and exclude local users by checking just the UserDomainName in the Form_Load. This simple approach piggybacks on their computer login, and does not have the complexity of any LDAP/AD calls.
if (SystemInformation.UserDomainName.ToString() == "myDomain")
{
// your normal form load code here
}
else
{
form1.Close(); //this is a simple but effective to pull the rug out from
//under them if they do not have the permissions
//TODO email the application administrator the `SystemInformation.UserName` of the user who was not given permissions
}
In my environment, since our in-house apps are deployed via ClickOnce (installed per user per computer), a similar approach (we compare usernames too) has always been sufficient for us.
If you want to know how to verify credentials to Active Directory in order to allow AD users in you application, you should check this.
You'll find how to verify the content of your textboxes and verify if username and passowrd matches (directly with the AD).

Categories

Resources