Created
May 21, 2025 22:09
-
-
Save RichardDally/d2b44b6f371a59c2ff7e27b5a06d2806 to your computer and use it in GitHub Desktop.
Generate Artifactory token
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import requests | |
import json | |
import logging | |
import os | |
# --- Logger Setup --- | |
logging.basicConfig( | |
level=logging.INFO, | |
format='%(asctime)s - %(levelname)s - %(message)s', | |
handlers=[ | |
logging.StreamHandler() # Log to console | |
# You could add logging.FileHandler("token_generation.log") here to log to a file | |
] | |
) | |
logger = logging.getLogger(__name__) | |
# --- Configuration --- | |
# These should ideally be set via environment variables or a secure config file | |
ARTIFACTORY_URL = os.getenv("ARTIFACTORY_URL", "https://YOUR_ARTIFACTORY_URL") | |
LDAP_USERNAME = os.getenv("ARTIFACTORY_LDAP_USERNAME", "your_ldap_username") | |
LDAP_PASSWORD = os.getenv("ARTIFACTORY_LDAP_PASSWORD", "your_ldap_password") | |
# Token details (optional, adjust as needed in your environment or configuration) | |
TOKEN_SCOPE = os.getenv("ARTIFACTORY_TOKEN_SCOPE", "api:*") | |
_expires_in_str = os.getenv("ARTIFACTORY_TOKEN_EXPIRES_IN_SECONDS") | |
TOKEN_EXPIRES_IN_SECONDS = int(_expires_in_str) if _expires_in_str and _expires_in_str.isdigit() else 3600 | |
_refreshable_str = os.getenv("ARTIFACTORY_TOKEN_REFRESHABLE", "True") | |
TOKEN_REFRESHABLE = _refreshable_str.lower() == 'true' | |
TOKEN_AUDIENCE = os.getenv("ARTIFACTORY_TOKEN_AUDIENCE") # e.g., "*@*" or specific service IDs | |
TOKEN_DESCRIPTION = os.getenv("ARTIFACTORY_TOKEN_DESCRIPTION", "Python generated token") | |
# --- API Endpoint --- | |
TOKEN_ENDPOINT = f"{ARTIFACTORY_URL.rstrip('/')}/artifactory/api/security/token" | |
def generate_token(): | |
""" | |
Generates an Artifactory access token using LDAP credentials. | |
""" | |
# --- Request Payload --- | |
payload = { | |
"username": LDAP_USERNAME, # Can be omitted if authenticating user is the token subject | |
"scope": TOKEN_SCOPE, | |
} | |
# Add optional parameters to the payload if they have been set | |
if TOKEN_EXPIRES_IN_SECONDS is not None: # 0 is a valid value for non-expiring (subject to global limits) | |
payload["expires_in"] = TOKEN_EXPIRES_IN_SECONDS | |
if TOKEN_REFRESHABLE is not None: | |
payload["refreshable"] = TOKEN_REFRESHABLE | |
if TOKEN_AUDIENCE: | |
payload["audience"] = TOKEN_AUDIENCE | |
if TOKEN_DESCRIPTION: | |
payload["description"] = TOKEN_DESCRIPTION | |
# --- Sensitive Data Check --- | |
if "YOUR_ARTIFACTORY_URL" in ARTIFACTORY_URL or \ | |
"your_ldap_username" == LDAP_USERNAME or \ | |
"your_ldap_password" == LDAP_PASSWORD: | |
logger.warning("Default placeholder values detected for URL or credentials. " | |
"Please configure them properly via environment variables or directly in the script.") | |
# return None # Optionally exit if not configured | |
logger.info(f"Attempting to generate token for user '{LDAP_USERNAME}' at '{TOKEN_ENDPOINT}'") | |
logger.debug(f"Request payload (excluding sensitive data if username is same as auth user): { {k:v for k,v in payload.items() if k != 'username' or payload.get('username') != LDAP_USERNAME} }") | |
try: | |
response = requests.post( | |
TOKEN_ENDPOINT, | |
auth=(LDAP_USERNAME, LDAP_PASSWORD), # Basic Authentication with LDAP credentials | |
json=payload # Send data as JSON | |
) | |
response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx) | |
token_data = response.json() | |
logger.info("--- Token Generated Successfully! ---") | |
# Avoid logging the full token directly to INFO unless necessary for debugging in controlled env | |
logger.debug(f"Full token data: {token_data}") | |
logger.info(f"Access Token: [REDACTED - see DEBUG log for full token if enabled]") # Or just log a portion token_data.get('access_token', '')[:10] + "..." | |
logger.info(f"Token Type: {token_data.get('token_type')}") | |
if "expires_in" in token_data: | |
logger.info(f"Expires In (seconds): {token_data.get('expires_in')}") | |
if "scope" in token_data: | |
logger.info(f"Scope: {token_data.get('scope')}") | |
if "refresh_token" in token_data: | |
logger.info(f"Refresh Token: [REDACTED - see DEBUG log for full token if enabled]") | |
return token_data | |
except requests.exceptions.HTTPError as errh: | |
logger.error("--- HTTP Error ---") | |
logger.error(f"Error: {errh}") | |
logger.error(f"Response Status Code: {errh.response.status_code}") | |
try: | |
error_details = errh.response.json() | |
logger.error(f"Response Body: {json.dumps(error_details, indent=2)}") | |
except json.JSONDecodeError: | |
logger.error(f"Response Body: {errh.response.text}") | |
except requests.exceptions.ConnectionError as errc: | |
logger.error("--- Error Connecting ---") | |
logger.error(f"Error: {errc}. Check ARTIFACTORY_URL and network connectivity.") | |
except requests.exceptions.Timeout as errt: | |
logger.error("--- Timeout Error ---") | |
logger.error(f"Error: {errt}") | |
except requests.exceptions.RequestException as err: | |
logger.error("--- Request Exception ---") | |
logger.error(f"Error: {err}") | |
except Exception as e: | |
logger.error("--- An unexpected error occurred ---") | |
logger.error(f"Error: {e}", exc_info=True) # exc_info=True will log stack trace | |
return None | |
if __name__ == "__main__": | |
generated_token_info = generate_token() | |
if generated_token_info: | |
# The token details are already logged by the function. | |
# You might want to use/store generated_token_info.get('access_token') here. | |
# For security, avoid printing the raw token to stdout in production scripts. | |
logger.info("Token generation process finished.") | |
# Example: print(f"Access Token: {generated_token_info.get('access_token')}") # If needed for piping | |
else: | |
logger.error("Token generation failed. Check logs for details.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment