I have a simple task but haven't got a workable solution to make this happen. I'd like to upload two local Excel Workbooks to my OneDrive account, by programming. Simple. I found the following code online to do this, however, the two fields are really confusing: client_secret and client_id. On developer page, I can find application id and application secret, but I don't see client_id and client_secret. I would assume client_id is about my OneDrive Userid, and the secret is some sort of password? But I don't find where I can get a clear description of them.
import onedrivesdk
from onedrivesdk.helpers import GetAuthCodeServer
redirect_uri = 'http://localhost:8080/'
client_secret = 'vwIK558#{[pscjkCHCMI68&'
scopes=['wl.signin', 'wl.offline_access', 'onedrive.readwrite']
client = onedrivesdk.get_default_client(
client_id='0000000048201716',
scopes=scopes)
auth_url = client.auth_provider.get_auth_url(redirect_uri)
code = GetAuthCodeServer.get_auth_code(auth_url, redirect_uri)
client.auth_provider.authenticate(code, redirect_uri, client_secret)
Have a look https://apps.dev.microsoft.com
You need to create a new App, there will also your secret.
And also check if the host address is configured correctly.
Look at this picture, have you added http://localhost:8080/?
Related
For a Python code base I would like to have developers accessing application secrets using Azure Key Vault, with the idea that when we deploy, the application also should be able to connect. Hence, I'm thinking Active Directory.
However, I can not find any examples on the interweb that show this with the Python SDK. Initially, I would think to retrieve the CLI user:
from azure.common.credentials import get_azure_cli_credentials
credentials, subscription_id, tenant_id = get_azure_cli_credentials(with_tenant=True)
and then use this retrieved set of credentials to access the key vault:
from azure.keyvault import KeyVaultClient
vault_url = "https://########.vault.azure.net/"
secret_name = "########"
secret_version = "########"
client = KeyVaultClient(credentials)
secret = client.get_secret(vault_url, secret_name, secret_version)
print(secret)
However, I retrieve an error that:
azure.keyvault.v7_0.models.key_vault_error_py3.KeyVaultErrorException: Operation returned an invalid status code 'Unauthorized'
I can confirm that credentials, subscription_id and tenant_id are correct, and that using the CLI, I can succesfully retrieve the secret content. So it must be some Python SDK-specific thing.
Any ideas?
It looks like this is a bug in the Python SDK.
https://github.com/Azure/azure-sdk-for-python/issues/5096
You can use your own AD username and password with the UserPassCredentials class. It's not the logged in user, but's it's probably as close as you'll get for now.
EG:
from azure.common.credentials import UserPassCredentials
credentials = UserPassCredentials('username','password')
client = KeyVaultClient(credentials)
secret = client.get_secret(vault_url, secret_name, secret_version)
print(secret)
I tried the same thing and had a different error ("...audience is invalid...") until I changed your first function call adding the resource parameter:
credentials, subscription_id, tenant_id =
get_azure_cli_credentials(resource='https://vault.azure.net', with_tenant=True)
With this change I was able to access secrets using the same code you show.
What about this code snippet? Comparing your code to the example, I don't see where you're setting the client_id or the tenant.
You’ll want to set the access policy for the key vault to allow the authenticated user to access secrets. This can be done in the portal. Bear in mind that key vault has an upper limit of 16 access definitions, so you’ll probably want to grant access to a group and add your users to that group.
As #8forty pointed out, adding a resource='https://vault.azure.net' parameter to your get_azure_cli_credentials call will resolve the issue.
However, there are new packages for working with Key Vault in Python that replace azure-keyvault:
azure-keyvault-certificates (Migration guide)
azure-keyvault-keys (Migration guide)
azure-keyvault-secrets (Migration guide)
azure-identity is also the package that should be used with these for authentication.
If you want to authenticate your Key Vault client with the credentials of the logged in CLI user, you can use the AzureCliCredential class:
from azure.identity import AzureCliCredential
from azure.keyvault.secrets import SecretClient
credential = AzureCliCredential()
vault_url = "https://{vault-name}.vault.azure.net"
secret_name = "secret-name"
client = SecretClient(vault_url, credential)
secret = client.get_secret(secret_name)
print(secret.value)
(I work on the Azure SDK in Python)
Anyone know if this is possible?
I just want to automate dropping some documents into my onedrive for business account.
I tried
import onedrivesdk
from onedrivesdk.helpers import GetAuthCodeServer
from onedrivesdk.helpers.resource_discovery import ResourceDiscoveryRequest
redirect_uri = 'http://localhost:8080'
client_id = 'appid'
client_secret = 'mysecret'
discovery_uri = 'https://api.office.com/discovery/'
auth_server_url='https://login.live.com/oauth20_authorize.srf?scope=wl.skydrive_update'
#auth_server_url='https://login.microsoftonline.com/common/oauth2/authorize',
auth_token_url='https://login.microsoftonline.com/common/oauth2/token'
http = onedrivesdk.HttpProvider()
auth = onedrivesdk.AuthProvider(http,
client_id,
auth_server_url=auth_server_url,
auth_token_url=auth_token_url)
auth_url = auth.get_auth_url(redirect_uri)
code = GetAuthCodeServer.get_auth_code(auth_url, redirect_uri)
auth.authenticate(code, redirect_uri, client_secret, resource=resource)
# If you have access to more than one service, you'll need to decide
# which ServiceInfo to use instead of just using the first one, as below.
service_info = ResourceDiscoveryRequest().get_service_info(auth.access_token)[0]
auth.redeem_refresh_token(service_info.service_resource_id)
client = onedrivesdk.OneDriveClient(service_info.service_resource_id + '/_api/v2.0/', auth, http)
I registered an APP and got a secret and id. But when I ran this I got scope is invalid errors. Plus it tries to launch a webpage which isn't great for a command line kinda environment. I think this SDK might be outdated as well because originally this script had login.microsoftonline, but that wasn't reachable so I changed it to login.live.com.
I wrote this sample code you posted. You replaced the auth_server_URLwith the authentication URL for Microsoft Account authentication, which can only be used to access OneDrive (the consumer product). You need to continue using the login.microsoftonline.com URL to log into your OneDrive for Business account.
You are correct that this pops up a dialog. However, you can write a little supporting code so that only happens the first time you log into a particular app. Follow these steps (assuming you are using the default implementation of AuthProvider:
Use the sample code above up through the line auth.redeem_refresh_token()
The AuthProvider will now have a Session object, which caches the credentials of the current user and session. Use AuthProvider.save_session() to save the credentials for later.
Next time you start your app, use AuthProvider.load_session() and AuthProvider.refresh_token() to retrieve the previous session and refresh the auth token. This will all be headless.
Take note that the default implementation of SessionBase (found here) uses Pickle and is not safe for product use. Make sure to create a new implementation of Session if you intend to deploy this app to other users.
Onerive's website shows "Not Yet" on "OneDrive SDK for Python" to "OneDrive for Business"
https://dev.onedrive.com/SDKs.htm
The github sample codes did not work for me either, it tried to popup a window of authentication, but IE can not find the address:
http://('https//login.microsoftonline.com/common/oauth2/authorize',)?redirect_uri=http%3A%2F%2Flocalhost%3A8080&client_id=034xxxx9-9xx8-4xxf-bexx-1bc5xxxxbd0c&response_type=code
or removed all the "-" in client id
http://('https//login.microsoftonline.com/common/oauth2/authorize',)?redirect_uri=http%3A%2F%2Flocalhost%3A8080&client_id=034xxxx99xx84xxfbexx1bc5xxxxbd0c&response_type=code
Either way, I got the same result, IE did not show the popup with a line "This page can’t be displayed"
I'm trying to use Apache Libcloud (Web) and reading the Documentation of how to use it with Amazon EC2 I'm stuck on a step at the beginning.
On this step:
from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver
cls = get_driver(Provider.EC2)
driver = cls('temporary access key', 'temporary secret key',
token='temporary session token', region="us-west-1")
You need to pass the temporary access data and tells you to read Amazon Documentation but also I've read the documentation I don't get very clear what I have to do to get my temporal credentials.
On the doc says that you can interact with the AWS STS API to connect to the endpoint but I don't understand how do you get the credentials. Moreover, on the example of Libcloud Web they use the personal credentials:
ACCESS_ID = 'your access id'
SECRET_KEY = 'your secret key'
So I'm a bit lost. How I can get my temporal credentials to use it on my code?
Thanks and regards.
If this code does not run on an EC2 instance I suggest you go with static credentials:
ACCESS_ID = 'your access id'
SECRET_KEY = 'your secret key'
cls = get_driver(Provider.EC2)
driver = cls(ACCESS_ID, SECRET_KEY, region="us-west-1")
to create access credentials:
Sign in to the Identity and Access Management (IAM) console at https://console.aws.amazon.com/iam/.
In the navigation pane, choose Users.
Choose the name of the desired user, and then choose the Security Credentials tab.
If needed, expand the Access Keys section and do any of the following:
Choose Create Access Key and then choose Download Credentials to save the access key ID and secret access key to a CSV file on your computer. Store the file in a secure location. You will not have access to the secret access key again after this dialog box closes. After you have downloaded the CSV file, choose Close.
if you want to run your code from an EC2 machine you can get temporary credentials by assuming an IAM role using the AWS SDK for Python https://boto3.readthedocs.io/en/latest/guide/quickstart.html by calling assume_role() on the STS service https://boto3.readthedocs.io/en/latest/reference/services/sts.html
#Aker666 from what I have found on the web, you're still expected to use the regular AWS api to obtain this information.
The basic snippet that works for me is:
import boto3
from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver
boto3.setup_default_session(aws_access_key_id='somekey',aws_secret_access_key='somesecret',region_name="eu-west-1")
sts_client = boto3.client('sts')
assumed_role_object = sts_client.assume_role(
RoleArn="arn:aws:iam::701********:role/iTerm_RO_from_TGT",
RoleSessionName='update-cloud-hosts.aviadraviv#Aviads-MacBook-Pro.local'
)
cls = get_driver(Provider.EC2)
driver = cls(assumed_role_object['Credentials']['AccessKeyId'], assumed_role_object['Credentials']['SecretAccessKey'],
token=assumed_role_object['Credentials']['SessionToken'], region="eu-west-1")
nodes = driver.list_nodes()
print(nodes)
Hope this helps anyone.
I am trying to use the OneDrive API Python SDK to upload files to an Office 365 E3 account SharePoint folder.
As described for OneDrive for business / SharePoint files I am using Azure AD that is included in my Office 365 E3 account for auth and have created a native client application app in Azure AD management.
I would expect that I need to point auth to Office 365:
mydomain.sharepoint.com
However, it appears the OneDrive API Python SDK (auth_provider.py) points auth to:
AUTH_SERVER_URL = "https://login.live.com/oauth20_authorize.srf"
AUTH_TOKEN_URL = "https://login.live.com/oauth20_token.srf"
This Github issue discussion indicates OneDrive API Business is still in beta but just changing base urls to mydomain.sharepoint.com urls is all that is needed to use SDK for OneDrive API Business eg:
AUTH_SERVER_URL = "https://mydomain.sharepoint.com/oauth20_authorize.srf"
AUTH_TOKEN_URL = "https://mydomain.sharepoint.com/oauth20_token.srf"
Is this correct?
Edited to ensure related additional questions are addressed too:
Is there anything else other than the auth urls that needs to be modified in the OneDrive API Python SDK to be used for OneDrive for Business / Sharepoint?
The Github README includes sample code for authentication which requires client_secret and scopes to be identified.
However the Azure Active Directory app creation process includes scope identification, and native client app doesn't require client_secret.
For my native client app authorization, I have just left client_secret and scopes blank in the sample code eg:
client_secret = ""
client = onedrivesdk.get_default_client(client_id='xxxxxetc',
scopes=[])
Auth for OneDrive for Business is handled by AAD, which means you need to point to the AAD OAuth 2 end points, which are:
AUTH_SERVER_URL = "https://login.microsoftonline.com/common/oauth2/authorize"
AUTH_TOKEN_URL = "https://login.microsoftonline.com/common/oauth2/token"
This is roughly documented here, https://dev.onedrive.com/auth/aad_oauth.htm, although since that is describing the authentication flow the details are a bit hidden if you were just looking for the two URLs to use with the SDK.
If you take a look at the onedrivesdk_helpers module, you'll see that it defaults to api.onedrive.com. I would recommend using the following code in place of get_default_client:
http_provider = HttpProvider()
auth_provider = AuthProvider(http_provider=http_provider,
client_id="your_app_id",
scopes=[])
client = OneDriveClient("mydomain.sharepoint.com",
auth_provider,
http_provider)
Make sure to import those classes with from onedrivesdk import HttpProvider, AuthProvider, OneDriveClient
I created service account for my account name#steelkiwi.com(Google apps) and my application works fine. Then I created service account for my personal account name#gmail.com, use this new credentials for my application and now when I try to insert files I get error 500 with next text:
HttpError 500 when requesting https://www.googleapis.com/upload/drive/v2/files?quotaUser=30&uploadType=resumable&convert=true&ocr=false&alt=json returned "Internal Error"
The only thing that changes is credentials SERVICE_ACCOUNT_EMAIL and SERVICE_ACCOUNT_PKCS12_FILE_PATH. I have tried to create another service account for name#steelkiwi.com but it doesn't help, so bacically my app only works with first service account.
Language is python.
If you create a service account with your apps domain admin, you should be able to impersonate all users by changing the prn attribute below. If you don't set a prn user that is out of your domain, you should see an access error.
f = open('path-to-privatekey.p12')
key = f.read()
f.close()
credentials = SignedJwtAssertionCredentials('xxx#developer.gserviceaccount.com', key, scope='https://www.googleapis.com/auth/drive', prn='user#steelkiwi.com')
http = httplib2.Http()
credentials.authorize(http)
client = build('drive', 'v2', http=http)
Ok, I'm not sure what happened maybe something was fixed after this accident http://www.google.com/appsstatus#hl=en&v=issue&ts=1366405199000&iid=369723584758ad9cdfd010ac44c8272e
but now all works fine. At first I created simple small app from examples that work with service accounts https://gist.github.com/mobedigg/5420958 I have used my credentials for this app and it's works so I put this credentials to my main code and it's worked too. Nothing was changed in main code except credentials. Also I tried other credentials on this small app and they are worked with it and worked with main code. It's very odd.