OpenStack - KeyStone Requires Authentication 401 - python

I'm trying to list the projects (but the same thing occurs whether I try to do that, or attempt to list the users, so let's just generalise the error to any API call). Every time I do this, I get the following HTTP 401 code:
File "/usr/lib/python2.7/site-packages/cherrypy/_cprequest.py", line 656, in respond
response.body = self.handler()
File "/usr/lib/python2.7/site-packages/cherrypy/lib/encoding.py", line 188, in __call__
self.body = self.oldhandler(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/cherrypy/lib/jsontools.py", line 61, in json_handler
value = cherrypy.serving.request._json_inner_handler(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/cherrypy/_cpdispatch.py", line 34, in __call__
return self.callable(*self.args, **self.kwargs)
File "/var/www/frontend/controllers/api/user.py", line 63, in PUT
print keystoneClient.projects.list()
File "/usr/lib/python2.7/site-packages/positional/__init__.py", line 101, in inner
return wrapped(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/keystoneclient/v3/projects.py", line 107, in list
**kwargs)
File "/usr/lib/python2.7/site-packages/keystoneclient/base.py", line 75, in func
return f(*args, **new_kwargs)
File "/usr/lib/python2.7/site-packages/keystoneclient/base.py", line 383, in list
self.collection_key)
File "/usr/lib/python2.7/site-packages/keystoneclient/base.py", line 124, in _list
resp, body = self.client.get(url, **kwargs)
File "/usr/lib/python2.7/site-packages/keystoneauth1/adapter.py", line 173, in get
return self.request(url, 'GET', **kwargs)
File "/usr/lib/python2.7/site-packages/keystoneauth1/adapter.py", line 331, in request
resp = super(LegacyJsonAdapter, self).request(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/keystoneauth1/adapter.py", line 98, in request
return self.session.request(url, method, **kwargs)
File "/usr/lib/python2.7/site-packages/positional/__init__.py", line 101, in inner
return wrapped(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/keystoneauth1/session.py", line 387, in request
auth_headers = self.get_auth_headers(auth)
File "/usr/lib/python2.7/site-packages/keystoneauth1/session.py", line 647, in get_auth_headers
return auth.get_headers(self, **kwargs)
File "/usr/lib/python2.7/site-packages/keystoneauth1/plugin.py", line 84, in get_headers
token = self.get_token(session)
File "/usr/lib/python2.7/site-packages/keystoneauth1/identity/base.py", line 90, in get_token
return self.get_access(session).auth_token
File "/usr/lib/python2.7/site-packages/keystoneauth1/identity/base.py", line 136, in get_access
self.auth_ref = self.get_auth_ref(session)
File "/usr/lib/python2.7/site-packages/keystoneauth1/identity/v3/base.py", line 167, in get_auth_ref
authenticated=False, log=False, **rkwargs)
File "/usr/lib/python2.7/site-packages/keystoneauth1/session.py", line 595, in post
return self.request(url, 'POST', **kwargs)
File "/usr/lib/python2.7/site-packages/positional/__init__.py", line 101, in inner
return wrapped(*args, **kwargs)
File "/usr/lib/python2.7/site-packages/keystoneauth1/session.py", line 484, in request
raise exceptions.from_response(resp, method, url)
Unauthorized: The request you have made requires authentication. (HTTP 401) (Request-ID: req-39d02130-6f47-4cae-bc30-0b645296752e)
Code:
import cherrypy
import ldap
from keystoneauth1 import loading
from keystoneauth1 import session as session
from keystoneclient.v3 import client as client
from keystoneauth1.identity import v3
import json
# Storing username and password in a cherrypy session
cherrypy.session['username'] = data.get("username")
cherrypy.session['password'] = data.get("password").replace(" ","%20")
# Setting up KeyStone Client
auth = v3.Password(
auth_url = KEYSTONE_URL,
username = cherrypy.session['username'],
password = cherrypy.session['password'],
user_domain_name="default",
domain_name = "default"
)
sess = session.Session(auth=auth, verify='/etc/ssl/certs/ca-bundle.crt')
keystoneClient = client.Client(session=sess)
# Getting list of projects
print keystoneClient.projects.list()
This occurs whilst using a normal user's credentials. If I login using admin credentials, there is no error and the projects are listed. I would like to know:
Why is the overall error occurring? (from what I've read, it seems like it has to reauthenticate the credentials and it doesn't like it?)
Why is it not happening when I use admin credentials but with a 'normal' users credentials?
How do I solve this?

To answer the first question, you need a project scoped token since the unscoped token doesn't have any role associated with it. You cannot do any operation with the unscoped token. Here is a way to get the project scoped token:
auth = v3.Password(auth_url=auth_url,
username=username,
password=password,
user_domain_name="default",
project_name=project_name,
project_domain_name="default")
sess = session.Session(auth=auth, verify='/etc/ssl/certs/ca-bundle.crt')
keystoneClient = client.Client(session=sess)
And for a normal user, you cannot get back the entire list of projects in the provider and this is why it works fine with using admin credentials but not for that of a normal user.
In order to solve it, you need to know the user_id of that normal user. One way is to use the admin credentials to get a keystone client and call
keystone.users.get(user="username")
Or just use the OpenStack Dashboard and go to the identity dashboard. There is a panel called User and you can see the user_id from there.
Once you have the user_id, you can do:
keystoneClient.projects.list(user=user_id)
HTH.

Related

Using aws encryption SDK try to encrypt the files but getting error in python

import aws_encryption_sdk
from aws_encryption_sdk.identifiers import CommitmentPolicy
client = aws_encryption_sdk.EncryptionSDKClient(commitment_policy=CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT
)
kms_key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(key_ids=['arn:aws:kms:ap-south-1:588105036995:key/ad1e065c-b51c-76'])
my_plaintext = 'D:\\test-2\\u_in220819.log'
my_ciphertext, encryptor_header = client.encrypt(
source=my_plaintext,
key_provider=kms_key_provider
)
"""
#-----------------------------
#Am getting below error.
'''
return self._emit(event_name, kwargs)
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python310\lib\site-packages\botocore\hooks.py", line 239, in _emit
response = handler(**kwargs)
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python310\lib\site-packages\botocore\signers.py", line 105, in handler
return self.sign(operation_name, request)
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python310\lib\site-packages\botocore\signers.py", line 189, in sign
auth.add_auth(request)
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python310\lib\site-packages\botocore\auth.py", line 418, in add_auth
raise NoCredentialsError()
on botocore.exceptions.NoCredentialsError: Unable to locate credentials
#Anyone who can give me pointers how to fix it?
"""

Error to connect firestore to store an API result made at Cloud Shell with Python

I just want to learn how to store data in Firestore using Python and Google Cloud Platform, so I'm calling an API to query some example data.
For it, I'm using requests library and Firebase library from google.cloud package.
Here is the code that I'm running at Cloud Shell:
import requests
from google.cloud import firestore
url = "https://api.coindesk.com/v1/bpi/currentprice.json"
r = requests.get(url)
resp: str = r.text
if not (resp=="null" or resp=="[]"):
db = firestore.Client()
doc_ref=db.collection("CoinData").add(r.json())
When the code try to connect to Firebase to add the json of the API response I got this error:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/google/api_core/grpc_helpers.py", line 66, in error_remapped_callable
return callable_(*args, **kwargs)
File "/usr/local/lib/python3.7/dist-packages/grpc/_channel.py", line 946, in __call__
return _end_unary_response_blocking(state, call, False, None)
File "/usr/local/lib/python3.7/dist-packages/grpc/_channel.py", line 849, in _end_unary_response_blocking
raise _InactiveRpcError(state)
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
status = StatusCode.INVALID_ARGUMENT
details = "Invalid resource field value in the request."
debug_error_string = "{"created":"#1634689546.004704998","description":"Error received from peer ipv4:74.125.134.95:443","file":"src/core/lib/surface/call.cc","file_line":1070,"grpc_message":"Invalid resource field value in the request.","grpc_status":3}"
>
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/antonyare_93/cloudshell_open/pruebas/data_coin_query.py", line 11, in <module>
doc_ref=db.collection("CoinData").add(r.json())
File "/home/antonyare_93/.local/lib/python3.7/site-packages/google/cloud/firestore_v1/collection.py", line 107, in add
write_result = document_ref.create(document_data, **kwargs)
File "/home/antonyare_93/.local/lib/python3.7/site-packages/google/cloud/firestore_v1/document.py", line 99, in create
write_results = batch.commit(**kwargs)
File "/home/antonyare_93/.local/lib/python3.7/site-packages/google/cloud/firestore_v1/batch.py", line 60, in commit
request=request, metadata=self._client._rpc_metadata, **kwargs,
File "/home/antonyare_93/.local/lib/python3.7/site-packages/google/cloud/firestore_v1/services/firestore/client.py", line 815, in commit
response = rpc(request, retry=retry, timeout=timeout, metadata=metadata,)
File "/usr/local/lib/python3.7/dist-packages/google/api_core/gapic_v1/method.py", line 142, in __call__
return wrapped_func(*args, **kwargs)
File "/usr/local/lib/python3.7/dist-packages/google/api_core/retry.py", line 288, in retry_wrapped_func
on_error=on_error,
File "/usr/local/lib/python3.7/dist-packages/google/api_core/retry.py", line 190, in retry_target
return target()
File "/usr/local/lib/python3.7/dist-packages/google/api_core/grpc_helpers.py", line 68, in error_remapped_callable
raise exceptions.from_grpc_error(exc) from exc
google.api_core.exceptions.InvalidArgument: 400 Invalid resource field value in the request.
Anyone knows how I can fix it?
I've just got it.
It was a little mistake, I was missing the name of the project at the firestore client method call, here's the code working:
import requests
from google.cloud import firestore
url = "https://api.coindesk.com/v1/bpi/currentprice.json"
r = requests.get(url)
resp: str = r.text
if not (resp=="null" or resp=="[]"):
db = firestore.Client(project="mytwitterapitest")
doc_ref=db.collection("CoinData").add(r.json())

Azure SDK for Python whoami call to get currently signed in user

I'd like to ask Azure for the details of the currently signed in user programmatically within a Python program. The program might run from the command line or within Azure batch.
Is there way to do the same thing as the azure cli does with az ad signed-in-user show, but through the Azure SDK for Python?
UPDATE:
Based on Gaurav's help and pointer to the Microsoft Graph Python Client Library, I tried the following:
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient, BlobClient, ContainerClient
from msgraphcore import GraphSession
credential = DefaultAzureCredential(
exclude_shared_token_cache_credential=True,
)
account_name = "mydatalake"
container_name = "test"
service = BlobServiceClient(
account_url=f"https://{account_name}.blob.core.windows.net/",
credential=credential
)
container_client = service.get_container_client(container_name)
blob_list = container_client.list_blobs()
for i, blob in enumerate(blob_list):
print("\t" + blob.name)
if i >= 9: break
scopes = ['user.read']
graph_session = GraphSession(credential, scopes)
result = graph_session.get('/me')
print(result.json())
I successfully get back blob names from a storage account. But it fails when it gets to the GraphAPI part with this stack trace:
Traceback (most recent call last):
File "py/src/azure_whoami.py", line 58, in <module>
result = graph_session.get('/me')
File "[...snip...]/site-packages/msgraphcore/middleware/options/middleware_control.py", line 24, in wrapper
return func(*args, **kwargs)
File "[...snip...]/site-packages/msgraphcore/graph_session.py", line 41, in get
return super().get(self._graph_url(url))
File "[...snip...]/site-packages/requests/sessions.py", line 555, in get
return self.request('GET', url, **kwargs)
File "[...snip...]/site-packages/requests/sessions.py", line 542, in request
resp = self.send(prep, **send_kwargs)
File "[...snip...]/site-packages/requests/sessions.py", line 655, in send
r = adapter.send(request, **kwargs)
File "[...snip...]/site-packages/msgraphcore/middleware/middleware.py", line 26,
in send
return self._middleware.send(request, **kwargs)
File "[...snip...]/site-packages/msgraphcore/middleware/authorization.py", line 16, in send
request.headers.update({'Authorization': 'Bearer {}'.format(self._get_access_token())})
File "[...snip...]/site-packages/msgraphcore/middleware/authorization.py", line 33, in _get_access_token
return self.credential.get_token(*self.scopes)[0]
File "[...snip...]/site-packages/azure/identity/_credentials/default.py", line 138, in get_token
token = self._successful_credential.get_token(*scopes, **kwargs)
File "[...snip...]/site-packages/azure/identity/_internal/decorators.py", line 27, in wrapper
token = fn(*args, **kwargs)
File "[...snip...]/site-packages/azure/identity/_credentials/azure_cli.py", line
58, in get_token
raise error
azure.identity._exceptions.CredentialUnavailableError: Please run 'az login' to set up an account
Based on the instructions provided here, you would first need to install the appropriate SDKs (msgraphcore and azure-identity).
After that your code would be something like (again taking from the same link)
# import modules
from azure.identity import UsernamePasswordCredential, DeviceCodeCredential
from msgraphcore import GraphSession
# Configuring credentials
# Added UsernamePassword for demo purposes only, please don't use this in production.
# ugly_credential = UsernamePasswordCredential('set-clientId', 'set-username', 'set-password')
device_credential = DeviceCodeCredential(
'set-clientId')
# There are many other options for getting an access token. See the following for more information.
# https://pypi.org/project/azure-identity/
# get data
scopes = ['user.read']
graph_session = GraphSession(device_credential, scopes)
result = graph_session.get('/me')
print(result.json())

How to authenticate nexmo voice client?

I am trying to make an outbound call using Nexmo (Vonage) API. To access the API, I am required to authenticate my client using an application id and a private key (given to me as a .key file).
The application id was specified as a string and the private key was specified as a path.
client = nexmo.Client(application_id = 'xxxxxx-xxxxxxx', private_key = "C:\\path\\to\\folder\\private.key")
I get the following error.
File "test_bot.py", line 30, in <module>
'ncco': ncco
File "C:\Users\vishn\AppData\Local\Programs\Python\Python37-32\lib\site-packages\wrapt\wrappers.py", line 606, in __call__
args, kwargs)
File "C:\Users\vishn\AppData\Local\Programs\Python\Python37-32\lib\site-packages\deprecated\classic.py", line 285, in wrapper_function
return wrapped_(*args_, **kwargs_)
File "C:\Users\vishn\AppData\Local\Programs\Python\Python37-32\lib\site-packages\nexmo\__init__.py", line 427, in create_call
return self._jwt_signed_post("/v1/calls", params or kwargs)
File "C:\Users\vishn\AppData\Local\Programs\Python\Python37-32\lib\site-packages\nexmo\__init__.py", line 719, in _jwt_signed_post
self.api_host(), self.session.post(uri, json=params, headers=self._headers())
File "C:\Users\vishn\AppData\Local\Programs\Python\Python37-32\lib\site-packages\nexmo\__init__.py", line 742, in _headers
return dict(self.headers, Authorization=b"Bearer " + token)
TypeError: can't concat str to bytes
Diana from Vonage here.
The fix is already on the way. However i noticed that this occurs only with pyjwt 2.0.

Trouble using configparser to pass API credentials

I have a config.ini file that looks like this
[REDDIT]
client_id = 'myclientid23jd934g'
client_secret = 'myclientsecretjf30gj5g'
password = 'mypassword'
user_agent = 'myuseragent'
username = 'myusername'
When I try to use reddit's API praw like this:
import configparser
import praw
class redditImageScraper:
def __init__(self, sub, limit):
config = configparser.ConfigParser()
config.read('config.ini')
self.sub = sub
self.limit = limit
self.reddit = praw.Reddit(client_id=config.get('REDDIT','client_id'),
client_secret=config.get('REDDIT','client_secret'),
password=config.get('REDDIT','password'),
user_agent=config.get('REDDIT','user_agent'),
username=config.get('REDDIT','username'))
def get_content(self):
submissions = self.reddit.subreddit(self.sub).hot(limit=self.limit)
for submission in submissions:
print(submission.id)
def main():
scraper = redditImageScraper('aww', 25)
scraper.get_content()
if __name__ == '__main__':
main()
I get this traceback
Traceback (most recent call last):
File "config.py", line 30, in <module>
main()
File "config.py", line 27, in main
scraper.get_content()
File "config.py", line 22, in get_content
for submission in submissions:
File "C:\Users\Evan\Anaconda3\lib\site-packages\praw\models\listing\generator.py", line 61, in __next__
self._next_batch()
File "C:\Users\Evan\Anaconda3\lib\site-packages\praw\models\listing\generator.py", line 71, in _next_batch
self._listing = self._reddit.get(self.url, params=self.params)
File "C:\Users\Evan\Anaconda3\lib\site-packages\praw\reddit.py", line 454, in get
data = self.request("GET", path, params=params)
File "C:\Users\Evan\Anaconda3\lib\site-packages\praw\reddit.py", line 627, in request
method, path, data=data, files=files, params=params
File "C:\Users\Evan\Anaconda3\lib\site-packages\prawcore\sessions.py", line 185, in request
params=params, url=url)
File "C:\Users\Evan\Anaconda3\lib\site-packages\prawcore\sessions.py", line 116, in _request_with_retries
data, files, json, method, params, retries, url)
File "C:\Users\Evan\Anaconda3\lib\site-packages\prawcore\sessions.py", line 101, in _make_request
params=params)
File "C:\Users\Evan\Anaconda3\lib\site-packages\prawcore\rate_limit.py", line 35, in call
kwargs['headers'] = set_header_callback()
File "C:\Users\Evan\Anaconda3\lib\site-packages\prawcore\sessions.py", line 145, in _set_header_callback
self._authorizer.refresh()
File "C:\Users\Evan\Anaconda3\lib\site-packages\prawcore\auth.py", line 328, in refresh
password=self._password)
File "C:\Users\Evan\Anaconda3\lib\site-packages\prawcore\auth.py", line 138, in _request_token
response = self._authenticator._post(url, **data)
File "C:\Users\Evan\Anaconda3\lib\site-packages\prawcore\auth.py", line 31, in _post
raise ResponseException(response)
prawcore.exceptions.ResponseException: received 401 HTTP response
However when I manually insert the credentials, my code runs exactly as expected. Also, if I run the line
print(config.get('REDDIT', 'client_id'))
I get the output 'myclientid23jd934g' as expected.
Is there some reason that praw won't allow me to pass my credentials using configparser?
Double check what your inputs to praw.Reddit are:
kwargs = dict(client_id=config.get('REDDIT','client_id'),
client_secret=config.get('REDDIT','client_secret'),
password=config.get('REDDIT','password'),
user_agent=config.get('REDDIT','user_agent'),
username=config.get('REDDIT','username')))
print(kwargs)
praw.Reddit(**kwargs)
You're overcomplicating configuration here — PRAW will take care of this for you.
If you rename config.ini to praw.ini, you can replace your whole initialization with just
self.reddit = praw.Reddit('REDDIT')
This is because PRAW will look for a praw.ini file and parse it for you. If you want to give the section a more descriptive name, make sure to update it in the praw.ini as well as in the single parameter passed to Reddit (which specifies the section of the file to use).
See https://praw.readthedocs.io/en/latest/getting_started/configuration/prawini.html.
As this page notes, values like username and password should not have quotation marks around them. For example,
password=mypassword
is correct, but
password="mypassword"
is incorrect.

Categories

Resources