No output for existing permissions on non-IBMid users? - python-3.x

I tried the example user permissions script at https://softlayer.github.io/python/set_permission/
It successfully lists existing user permissions for users with IBMids, but if I try a user without an IBMid, for example the account owner, or the brand master account, I get no output for existing permissions. Is this expected?
The specific section of code in the example script that lists permissions is:
def main(self, user_id):
permissions = self.client['User_Customer'].getPermissions(id=user_id)
print("=== OLD PERMISSIONS ===")
self.printPermissions(permissions)
#setperm = {'keyName': "TICKET_ADD"}
#self.client['User_Customer'].addPortalPermission(setperm, id=user_id)
#permissions = self.client['User_Customer'].getPermissions(id=user_id)
#print("=== NEW PERMISSIONS ===")
#self.printPermissions(permissions)
I'm specifically interested in the old (existing) permissions part. I have opened a ticket about this internally (ticket 57783823), and the recommendation was to come here first. Thanks for any help you can provide.

It is expected to get empty response when you trying to get permission of master and brand account, because it is by design.
To get all users into the account and their permissions use the following rest, with this rest, you will get all users, their child’s and the permissions.
Method:
GET
https://[username]:[apiKey]#api.softlayer.com/rest/v3.1/SoftLayer_Account/getUsers?objectMask=mask[id,parentId,firstName,lastName,permissions,childUsers]
finally, to get all available permissions you can use the following rest api:
Method: GET
https://[username]:[apiKey]#api.softlayer.com/rest/v3.1/SoftLayer_User_Customer_CustomerPermission_Permission/getAllObjects

Related

Get users' email with Jira Python Library

I've been trying to get the email of a Jira user other than my own with the Python3 Jira library, but couldn't do it. It either gives me an error, saying I don't have enough permissions to get it, or only returns me simple information, like display names. Here's my code:
from jira import JIRA
conn = JIRA(
options={"server": "https://example.atlassian.net"},
basic_auth=("my.email#gmail.com", TOKEN),
)
conn.user(id='my_id').emailAddress # Returns my email and more information
conn.user(id='another_user_id').emailAddress # Doesn't return his email
How could I get someone's email?
And what kind of permissions could I need?
To access another user's email in Jira, you'll need to have the "View User" permission in Jira. You can check this by navigating to the Jira administration page, clicking on Users, and checking the permissions for the user you want to access. If you do not have the "View User" permission, you will not be able to retrieve the email address of another user.
If you do have the "View User" permission, but still cannot retrieve the email address, you could try the following code:
from jira import JIRA
conn = JIRA(
options={"server": "https://example.atlassian.net"},
basic_auth=("my.email#gmail.com", TOKEN),
)
user = conn.user(id='another_user_id')
email = user.emailAddress
print(email)
Note that the emailAddress property is only available in Jira versions 7.3 and later. If you're using an earlier version of Jira, you may need to upgrade to access this property.

How to programmatically access Sharepoint sites other than root from Office365-REST-Python-Client?

I need to programmatically access my organization's Office 365 Sharepoint. In particular, at the moment I need to be able to upload and download files from specific lists/paths.
I created an Azure AD application using this manual and granted Sites.FullControl.All permission (consent was granted by the admin as well).
I am using Office365-REST-Python-Client Python library for calling Sharepoint API, which seems to be a well-maintained library and accepted in the Sharepoint community.
I was able to authenticate as my app using a certificate I created:
from office365.sharepoint.client_context import ClientContext
base_url = 'https://my-company.sharepoint.com/'
cert_auth_data = dict(
tenant='61ad46cb-b256-451d-9b4c-b592d46a7dc1',
client_id='b3af34ed-1335-468b-a82b-d0cf6ec79683',
thumbprint='815B134CD6D15EB0F07D247940AA6EF96263859F',
cert_path='selfsigncert.pem',
)
ctx = ClientContext(base_url).with_client_certificate(**cert_auth_data)
res = ctx.web.get().execute_query()
print(res.properties['Title']) # Works
Now I need to access a specific site in the portal, and this is where I start having problems. If I put https://my-company.sharepoint.com/sites/mysite as URL, I receive the following error:
ValueError: {'error': 'invalid_resource', 'error_description': 'AADSTS500011: The resource principal named https://my-company.sharepoint.com/sites/mysite was not found in the tenant named My Company Limited. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.\r\nTrace ID: e8bbbe6c-f5ef-4d6a-8635-0848184e1801\r\nCorrelation ID: f6a57e34-886a-4247-8a4e-194f098876ed\r\nTimestamp: 2022-05-12 02:26:44Z', 'error_codes': [500011], 'timestamp': '2022-05-12 02:26:44Z', 'trace_id': 'e8bbbe6c-f5ef-4d6a-8635-0848184e1801', 'correlation_id': 'f6a57e34-886a-4247-8a4e-194f098876ed', 'error_uri': 'https://login.microsoftonline.com/error?code=500011'}
I assumed I can somehow reach the site from the ClientContext of the base URL, but I could not figure how to do it and if that is possible at all.
I tried to use Site API:
site = Site.from_url(site_url)
But I see that Site lacks with_client_certificate() (as opposed to ClientContext) and has only with_credentials() method. I added such a method similarly to ClientContext:
def with_client_certificate(self, tenant, client_id, thumbprint, cert_path, **kwargs):
self.context.with_client_certificate(tenant, client_id, thumbprint, cert_path, **kwargs)
return self
However in this case authorization fails with the same error as above.
Is my application lacking some permissions? If yes, how to fix that?
Am I using the library properly? I failed to find good examples in their repo for my case, but other resources suggest that using site URL is probably the right way [1], [2].

Unexpected 403 in Sharepoint rest api list items roleassignments call

We created a sharepoint add-in with the follow permissions:
<AppPermissionRequests AllowAppOnlyPolicy="true"><AppPermissionRequest Scope="http://sharepoint/content/tenant" Right="Read"/></AppPermissionRequests>
My understanding is that an app with tenant scope permissions should be able to read all the site contents. In this case the call to
/_api/web/lists('<id>')/items(<id>)/roleassignments
fails with the following error:
Client error 403
{
"odata.error":
{
"code":"-2147024891, System.UnauthorizedAccessException",
"message":
{
"lang":"en-US",
"value":"Access denied. You do not have permission to perform this action or access this resource."
}
}
}
Note that a call to /_api/web/lists('<id>')/items(<id>) for the same item works fine. The roleassignments call with tenant permissions is also working for one of the SPO instances but not for a different one.
We've struggled with this issue on and off, because the solution is not obvious, nor even sensible from a least-privilege perspective. In short:
Your application requires FullControl rights in order to access RoleAssignments.
More details
If using an application created by Azure AD, you can demonstrate this by granting and consenting to SharePoint permissions such as:
AllSites.Read (delegated)
MyFiles.Read (delegated)
Sites.Selected (application)
User.Read.All (delegated)
User.Read.All (application)
If using SharePoint-created application, use appregnew.aspx and appinv.aspx to create the app and grant it Read rights at some reasonable scope; try http://sharepoint/content/tenant.
Then get a bearer token using a client_credentials workflow (use Postman, for example).
Try a query like:
https://your-tenant.sharepoint.com/_api/web/GetFolderByServerRelativeUrl('/Shared Documents')/Files?$select=Length,TimeLastModified,ListItemAllFields,ServerRelativeUrl
Make sure the Authorization header value is Bearer your-access-token
It will work.
Now try the same query, but with getting role assignments:
https://your-tenant.sharepoint.com/_api/web/GetFolderByServerRelativeUrl('/Shared Documents')/Files?$select=Length,TimeLastModified,ListItemAllFields,ServerRelativeUrl&$expand=ListItemAllFields/RoleAssignments/RoleDefinitionBindings/Name
It will fail as you described, with status 403 and System.UnauthorizedAccessException.
Now grant and consent to the SharePoint application permission Sites.FullControl.All, or use appinv.aspx to add FullControl rights. Get a new bearer token. (The old one encodes the old rights granted to the app in the role field of the payload.). You'll need to wait a few minutes until the permissions apparently propagate from AD to SharePoint, if you're using an Azure AD application.
Try the last query again, and it will work.
IMHO, requiring FullControl in order to resolve something like a role assignment, which is needed to capture the permissions required to access content in a SharePoint library, is unjustified. I could understand, sort of, if tenant-scope Read permission were required. However, granting AllSites.Read or tenant-scope (http://sharepoint/content/tenant in appinv.aspx XML permissions) doesn't seem to enable roleassignment lookup.

Accessing an organization-restriced Google Sheet via API

I am writing a Python 3.7 script that needs to read data from a Google Spreadsheet.
The spreadsheet in question belongs to an Organization that my work Google Account is part of: let's just call it "Organization". The spreadsheet permissions are set as "Anyone at Organization with the link can view". This detail has been preventing my application from working.
I went to the credentials dashboard at https://console.cloud.google.com/apis/credentials while being authenticated with my account in Organization, and created a Service Account Key. Domain Wide Delegation is allowed, as per Using New Google API Console project getting unauthorized_client ,Client is unauthorized to retrieve access tokens using this method. I downloaded the JSON keyfile to /path/to/service_account_key.json.
Below I document my attempt with the gspread client library - https://github.com/burnash/gspread - however I had the exact same problem using google-api-python-client 1.7.4:
import gspread
from oauth2client.service_account import ServiceAccountCredentials
scopes = ['https://www.googleapis.com/auth/spreadsheets.readonly']
credentials = ServiceAccountCredentials.from_json_keyfile_name('/path/to/service_account_key.json', scopes)
gc = gspread.authorize(credentials)
# spreadhseet ID below obfuscated, it's actually the one you get from its URL
sheet = gc.open_by_key('12345-abcdef')
gspread's response has the same HTTP code and message as the plain Google API v4:
gspread.exceptions.APIError: {
"error": {
"code": 403,
"message": "The caller does not have permission",
"status": "PERMISSION_DENIED"
}
}
However if I change the permissions on the spreadsheet (which I won't be allowed to do on the actual one) to "Anyone with the link can view", thus removing Organization", everything works!
<Spreadsheet 'Your spreadsheet' id:12345-abcdef>
My rough guess was that the service account I created did not inherit from me the membership in Organization. However I found no option for ensuring that. I even asked the domain Administrator to create the service account for me from his Admin accounts (also with Domain-wide Delegation on): nothing.
It has been said at Google service account and sheets permissions that I must explicitly share the sheet with the email address of the service account. When I did that it worked, but I also got a warning message claiming that account was not in the G Suite domain of Organization (again, how could it not be?).
Many Thanks
Try delegating that account to a specific user of your organization.
it goes as
from oauth2client.service_account import ServiceAccountCredentials
from httplib2 import Http
scope = [
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/spreadsheets.readonly',
'https://www.googleapis.com/auth/spreadsheets'
]
creds = ServiceAccountCredentials.from_json_keyfile_dict('/path_to_service_account_json_key', scope)
delegated = creds.create_delegated('anyuser#org_domain.com')
delegated_http = delegated.authorize(Http())
spreadsheetservice = gspread.authorize(delegated)
This would make the service account delegated as the user.
now you may simply share that very sheet to the above mentioned user (anyuser#org_domain.com) or pass the sheet's owner email dynamically.

Cannot access site groups with user with manage hierarchy permissions

I have a custom form that lists the site groups and the users in each group.
the form has twi drop down lists: one to display the site's group and the other to display the users in that group.
when I log to the form with the administrator user it works fine.
But if I log in with a user with manage hierarchy permission level, it omly displays the info of the domain groups and if I try to access a sharepoint group I get an access denied error.
I use run with elevated permissions in my code
I really don't know what to do in this
thanks.
Two common mistakes when using RunWithElevatedPrivileges is:
Using the SPContext.Current.Web (or Site etc) won't change the identity of the web object, it is already in memory.
Declaring the SPWeb outside the delegate, with similar results of mistake 1
That said, try something like:
Guid siteId = SPContext.Current.Site.Id;
SPSecurity.RunWithElevatedPrivileges(() =>
using (SPSite elevatedSite = new SPSite(siteId))
using (SPWeb elevatedWeb = elevatedSite.RootWeb)
{
//impl
});

Resources