GitLab CE API: Check if used token has admin rights - python

I am working on a Python module for the GitLab API. Is there any possibility to check if the user with the private token in use has admin rights on the GitLab server?
One way would be to get something from the API, e.g. a single user and check, if it has the elements only the admin can see like two_factor_enabled. But is there a better, easier way?

According to the api help the is_admin key is now included for all single user api queries.
I just tested it with the api v4 on gitlab.com with the query:
curl --header "PRIVATE-TOKEN: Token" https://gitlab.com/api/v4/users/###
and the json answer included "is_admin":false for the specified user with the id ###.

Can run a query that works just for admins, for example:
curl --header "PRIVATE-TOKEN: Token" https://my.gitlab.host/api/v4/users?admins=true
Because admins=true works only for users with admin-rights, if you get any reply it means that token has admin-rights.
(from: GitLab Docs: Users API - For Administrators)

If you GET /users and pass the sudo parameter you will get a JSON back that includes an is_admin attribute with a boolean value. You could use that Here is the documentation

Related

How should I check and validate request format and parameters with flask?

For now, my idea is to validate the below request by writing in decorators.py before the request is passed into the init.py including the endpoints. But Im not sure of how I can write the validation code of request with flask. Would anyone help me write this code ?
This is the http request which will be sent from curl command.
AUTH_HEADER=`echo -n ${ID}:${SECRET}|base64`
curl ${URL_HEADER}/oauth/token -X POST -H "Authorization: Basic ${AUTH_HEADER}" –d "grant_type=xxx&scope=yyy"
If you are unsure, especially when it comes to security - do not try to invent things yourself.
For Flask, there is an excellent package Flask-Security which provides:
Session based authentication
Role management
Password hashing
Basic HTTP authentication
Token based authentication
Token based account activation (optional)
Token based password recovery / resetting (optional)
User registration (optional)
Login tracking (optional)
JSON/Ajax Support

I got some problem in python env when use GCP api key

I want to use google translation api but I have some problems.
My env is Linux ubuntu 18 and python with Atom idle
I was used gcloud to set my configuration and got auth login, auth login token.
export GOOGLE_APPLICATION_CREDENTIALS=//api_key.json
gcloud init
gcloud auth application-default login
gcloud auth application-default print-access-token
so I could use curl and got some test data
curl -X POST -H "Authorization: Bearer "$(gcloud auth application-default print-access-token) -H "Content-Type: application/json; charset=utf-8" --data
"{
'q': 'Hello world',
'q': 'My name is Jeff',
'target': 'de'
}" "https://translation.googleapis.com/language/translate/v2"
{
"data": {
"translations": [
{
"translatedText": "Hallo Welt",
"detectedSourceLanguage": "en"
},
{
"translatedText": "Mein Name ist Jeff",
"detectedSourceLanguage": "en"
}
]
}
}
When I run test code in Atom idle, my project number is wrong.
It is my past project.
Even I run test code in bash python, it is same situation
I dont know what is wrong, I just guess some problem in python env.
raised error
raise exceptions.from_http_response(response)
google.api_core.exceptions.Forbidden: 403 POST
https://translation.googleapis.com/language/translate/v2: Cloud Translation
API has not been used in project [wrong number] before or it is disabled.
Enable it by visiting
https://console.developers.google.com/apis/api/translate.googleapis.com
/overview?project=[wrong number] then retry. If you enabled this API
recently, wait a few minutes for the action to propagate to our systems and
retry.
This error message is usually thrown when the application is not being authenticated correctly due to several reasons such as missing files, invalid credential paths, incorrect environment variables assignations, among other causes. Since the Client Libraries need to pull the credentials data from the environment variable or the client object, it is required to ensure you are pointing to the correct authentication files. Keep in mind this issue might not occur when using CURL command because you were passing the access-token directly.
Based on this, I recommend you to confirm that you are using the JSON file credentials of your current project, as well as follow the Obtaining and providing service account credentials manually guide in order to explicitly specify your service account file directly into your code; In this way, you will be able to set it permanently and verify if you are passing the service credentials correctly. Additionally, you can take a look on Using Client Libraries guide that contains the step-by-step process required to use the Translation API with Python.
Passing the path to the service account key in code example:
def explicit():
from google.cloud import storage
# Explicitly use service account credentials by specifying the private key
# file.
storage_client = storage.Client.from_service_account_json('service_account.json')
# Make an authenticated API request
buckets = list(storage_client.list_buckets())
print(buckets)

Google Admin Directory API - Send a query via apiclient

I am retrieving a ChromeOS device MAC address via the Google Admin Directory API using the device's Serial Number as reference, and am making my calls through
apiclient.
service = discovery.build('admin', 'directory_v1', developerKey=settings.API_KEY)
Here are the calls available for ChromeOS devices; my issue is that I require a Device ID in order to execute the following:
service.chromeosdevices().get(customerId=settings.CID, deviceId=obtained_id, projection=None).execute()
I can send a GET query via the following format:
https://www.googleapis.com/admin/directory/v1/customer/my_customer/devices/chromeos?projection=full&query=id:" + serial + "&orderBy=status&sortOrder=ascending&maxResults=10", "GET")
... but I'm trying to avoid using OAuth2 and just use my API key. Passing the key in a GET request doesn't work either, as it still returns a "Login Required" notice.
How do I squeeze the above query into an apiclient-friendly format? The only option I found via the above calls was to request every device we have (via list), then sift through the mountain of data for the matching Serial number, which seems silly and excessive.
I did notice I could call apiclient.http.HttpRequests, but I couldn't find a way to pass the API key through it either. There's new_batch_http_request, but I can't discern from the docs how to simply pass a URL to it.
Thank you!
Got it!
You can't use just a key for Directory API queries, you need a Service account.
I'm using google-auth (see here) since oauth2client is deprecated.
You also need to:
Delegate the necessary permissions for your service account (mine has the role of Viewer and has scope access to https://www.googleapis.com/auth/admin.directory.device.chromeos.readonly)
Delegate API access to it separately in the Admin Console (Security -> Advanced Settings -> Authentication)
Get your json client secret key and place it with your app (don't include it in your VCS)
Obtain your credentials like this:
credentials = service_account.Credentials.from_service_account_file(
settings.CLIENT_KEY,
scopes=settings.SCOPES,
subject=settings.ADMIN_USER)
where ADMIN_USER is the email address of an authorized Domain admin.
Then you send a GET request like so:
authed_session = AuthorizedSession(credentials)
response = authed_session.get(request_id_url)
This returns a Requests object you can read via response.content.
Hope it helps someone else!

How to authenticate in Jenkins while remotely accessing its JSON API?

I need to access the Jenkins JSON API from a Python script. The problem is that our Jenkins installation is secured so to log in users have to select a certificate. Sadly, in Jenkins Remote Access Documentation they don't mention a thing about certificates and I tried using the API Token without success.
How can I get to authenticate from a Python script to use their JSON API?
Thanks in advance!
You have to authenticate to the JSON API using HTTP Basic Auth.
To make scripted clients (such as wget) invoke operations that require authorization (such as scheduling a build), use HTTP BASIC authentication to specify the user name and the API token. This is often more convenient than emulating the form-based authentication
https://wiki.jenkins-ci.org/display/JENKINS/Authenticating+scripted+clients
Here is a sample of using Basic Auth with Python.
http://docs.python-requests.org/en/master/user/authentication/
Keep in mind if you are using a Self Signed certificate on an internal Jenkin Server you'll need to turn off certificate validation OR get the certificate from the server and add it to the HTTP request
http://docs.python-requests.org/en/master/user/advanced/
I finally found out how to authenticate to Jenkins using certs and wget. I had to convert my pfx certificates into pem ones with cert and keys in separate files For more info about that come here. In the end this is the command I used.
wget --certificate=/home/B/cert.pem --private-key=/home/B/key.pem --no-check-certificate --output-document=jenkins.json https:<URL>
I'm not completely sure it covers your certificate use case, but since it took me some time to find out, I still want to share this snipped that retrieves the email address for a given user name in Python without special Jenkins libraries. It uses an API token and "supports" (actually ignores) https:
def _get_email_adress(user):
request = urllib.request.Request("https://jenkins_server/user/"+ user +"/api/json")
#according to https://stackoverflow.com/a/28052583/4609258 the following is ugly
context = ssl._create_unverified_context()
base64string = base64.b64encode(bytes('%s:%s' % ('my user name', 'my API token'),'ascii'))
request.add_header("Authorization", "Basic %s" % base64string.decode('utf-8'))
with urllib.request.urlopen(request, context=context) as url:
user_data = json.loads(url.read().decode())
for property in user_data['property']:
if property["_class"]=="hudson.tasks.Mailer$UserProperty":
return property["address"];

Google AdWords API access w/ grant_type password

I have a server side application in python that is calling the AdWords API. Since ClientLogin is being deprecated I'm going to have to use OAuth 2.0.
Basically I need to generate an access token but I don't want any user interaction (to allow access the app) because I'm always using the same username and password on the server, and I'd like to use that username and password to make the AdWords API calls.
I believe the right way to do it is through a grant_type of 'password' oauth2 call to https://accounts.google.com/o/oauth2/token.
And this is what I understood from the OAuth2.0 RFC (https://www.rfc-editor.org/rfc/rfc6749#page-38). The RFC says that the request/query string must contain 3 parameters: grant_type (set to 'password'), username and password.
So I constructed my curl script, which looks like:
curl -v --data "grant_type=password&username=user#gmail.com&password=password" https://accounts.google.com/o/oauth2/token
But I launch the command and I get back with the response from google:
{"error" : "invalid_request"}
Am I missing something? Is there a simple python library that supports grant_type=password and that has a decent enough documentation?
This grant type isn't supported by the AdWords API, so you can't get an access token using a username and password, but you can get one using a refresh token. Your application just needs to store the refresh token and use it to get new access tokens from the OAuth API. You only need to authorize the account and get the code once; after you input the code into the example, you'll get an access and refresh token.
Here's an outline of the process:
1: Construct an authorization URL:
https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=1234567890123.apps.googleusercontent.com&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://adwords.google.com/api/adwords/&access_type=offline
Note the access_type of offline that requests a refresh token, which you can use to generate new access tokens when they expire.
2: Browse to the URL and authorize your account.
3: Extract the code from the redirect page, and request your access and refresh tokens:
curl -v --data "code=4/v6xr77ewYqhvHSyW6UJ1w7jKwAzu&client_id=8819981768.apps.googleusercontent.com&client_secret={client_secret}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code" https://accounts.google.com/o/oauth2/token
This should return your access and refresh tokens:
{
"access_token":"1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in":3920,
"token_type":"Bearer",
"refresh_token":"1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}
4: The access token only lasts for an hour, but you can use the refresh token to generate a new one without repeating steps 1-3:
curl -v --data "client_id=8819981768.apps.googleusercontent.com&
client_secret={client_secret}&refresh_token=1/xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI&
grant_type=refresh_token" https://accounts.google.com/o/oauth2/token
You can find a Python-specific example here.

Categories