Skip to content

Commit

Permalink
feat(OpenAI): Openai Api Key added
Browse files Browse the repository at this point in the history
  • Loading branch information
Vigneshkna committed Nov 20, 2024
1 parent d79735b commit 34376cf
Show file tree
Hide file tree
Showing 6 changed files with 249 additions and 3 deletions.
4 changes: 3 additions & 1 deletion src/js/how2validate/handler/validator_handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { validateGitHubPersonalAccessToken } from "../validators/github/github_p
import { validateHFOrgApiKey } from "../validators/hugging_face/hf_org_api_key.js"; // Import the Hugging Face API Key validator
import { validateHFUserAccessToken } from "../validators/hugging_face/hf_user_access_token.js"; // Import the Hugging Face API Key validator
import { validateNpmAccessToken } from "../validators/npm/npm_access_token.js"; // Import the NPM access token validator
import { validatePagerDutyAPIKey } from "../validators/pagerduty/pagerduty_api_key.js"; // Import the PagerDuty validator
import { validateOpenAIApiKey } from "../validators/openai/openai_api_key.js"; // Import the NPM access token validator
import { validatePagerDutyAPIKey } from "../validators/pagerduty/pagerduty_api_key.js"; // Import the OpenAI API key validator
import { validateSentryAuthToken } from "../validators/sentry/sentry_auth_token.js"; // Import the Sentry Auth Token validator
import { validateSnykAuthKey } from "../validators/snyk/snyk_auth_key.js"; // Import the Snyk authentication key validator
import { validateSonarcloudToken } from "../validators/sonarcloud/sonarcloud_token.js"; // Import the Sonarcloud token validator
Expand Down Expand Up @@ -51,6 +52,7 @@ const serviceHandlers: Record<string, ValidatorFunction> = {
hf_org_api_key: validateHFOrgApiKey, // HuggingFace API Key
hf_user_access_token: validateHFUserAccessToken, // HuggingFace API Key
npm_access_token: validateNpmAccessToken, // NPM access token validator
openai_api_key: validateOpenAIApiKey, // OpenAI API key
pagerduty_api_key: validatePagerDutyAPIKey, // PagerDuty API key
sentry_auth_token: validateSentryAuthToken, // Sentry Auth Token
snyk_auth_key: validateSnykAuthKey, // Snyk auth key validator
Expand Down
129 changes: 129 additions & 0 deletions src/js/how2validate/validators/openai/openai_api_key.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/**
* @module OpenAIApiKeyValidator
* @description
* This module provides functionality to validate an OpenAI API key by making an API call to the OpenAI service.
* It returns a validation status, processes the response from the API, and optionally sends an email report with the results.
*
* This module depends on various utilities for handling configuration, logging, and secret statuses.
*
* @requires axios - Used for making HTTP requests to the OpenAI API.
* @requires ../../utility/tool_utility.js - Utility functions for handling status responses and errors.
* @requires ../../handler/email_handler.js - Used for sending email reports on validation results.
*/

import { ValidationResult } from "../../utility/interface/validationResult.js";
import {
handleInactiveStatus,
handleErrors,
getUsernameFromEmail,
handleActiveStatus,
responseValidation,
} from "../../utility/tool_utility.js";
import { EmailResponse } from "../../utility/interface/EmailResponse.js";
import { SecretStatusMessage } from "../../utility/interface/secretStatusMessage.js";
import { sendEmail } from "../../handler/email_handler.js";
import axios from "axios";

/**
* @function validateOpenAIApiKey
* @description
* This function validates an OpenAI API key by making an API call to the OpenAI API.
* Based on the response from OpenAI, it checks the validity of the key, handles errors, and
* returns an appropriate validation result.
*
* If a `report` email is provided, the function also sends an email summarizing the validation results.
*
* @async
* @param {string} provider - The provider name (e.g., "OpenAI") for which the secret is being validated.
* @param {string} service - The name of the service being validated.
* @param {string} secret - The OpenAI API key to validate.
* @param {boolean} responseFlag - A flag to indicate whether detailed response data should be returned.
* @param {string} [report] - An optional email address to which a validation report should be sent.
* @param {boolean} [isBrowser=true] - Indicates if the function is called from a browser environment (default is false).
*
* @returns {Promise<ValidationResult>} - A promise that resolves to a `ValidationResult` object containing the validation result.
*
* @throws {Error} - If the validation process encounters an issue, it throws an error.
*/
export async function validateOpenAIApiKey(
provider: string,
service: string,
secret: string,
responseFlag: boolean,
report: string,
isBrowser: boolean = true
): Promise<ValidationResult> {
const validation_response = {} as SecretStatusMessage;

const url = "https://api.openai.com/v1/organizations";
const headers = { Authorization: `Bearer ${secret}` };

try {
const responseData = await axios.get(url, { headers });

if (responseData.status === 200) {
const activeResponse = handleActiveStatus(
provider,
service,
responseData,
responseFlag,
report,
isBrowser
);

validation_response.state = activeResponse.data?.validate.state!;
validation_response.message = activeResponse.data?.validate.message!;
validation_response.response = activeResponse.data?.validate.response!;

return responseValidation(activeResponse, responseFlag);
} else {
const inactiveResponse = handleInactiveStatus(
provider,
service,
responseFlag,
responseData.data,
report,
isBrowser
);

validation_response.state = inactiveResponse.data?.validate.state!;
validation_response.message = inactiveResponse.data?.validate.message!;
validation_response.response = inactiveResponse.data?.validate.response!;

return responseValidation(inactiveResponse, responseFlag);
}
} catch (error) {
const errResponse = handleErrors(
provider,
service,
responseFlag,
report,
error,
isBrowser
);

validation_response.state = errResponse.data?.validate.state!;
validation_response.message = errResponse.data?.validate.message!;
validation_response.response = errResponse.data?.validate.response!;

return responseValidation(errResponse, responseFlag);
} finally {
if (report) {
const emailResponse: EmailResponse = {
provider: provider,
service: service,
state: validation_response.state,
message: validation_response.message,
response: validation_response.response,
};

sendEmail(report, getUsernameFromEmail(report), emailResponse)
.then(() => {
console.info("Validation report sent successfully");
})
.catch((error) => {
console.error("Error sending validation report", error);
});
}
}
}
2 changes: 1 addition & 1 deletion src/js/tokenManager.json
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,7 @@
{
"secret_type": "openai_api_key",
"display_name": "Openai Api Key",
"is_enabled": false
"is_enabled": true
}
],
"Orbit": [
Expand Down
3 changes: 3 additions & 0 deletions src/python/how2validate/handler/validator_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from how2validate.validators.hugging_face.hf_org_api_key import validate_hf_org_api_key
from how2validate.validators.hugging_face.hf_user_access_token import validate_hf_user_access_token
from how2validate.validators.npm.npm_access_token import validate_npm_access_token
from how2validate.validators.openai.openai_api_key import validate_openai_api_key
from how2validate.validators.pagerduty.pagerduty_api_key import validate_pagerduty_api_key
from how2validate.validators.sentry.sentry_auth_token import validate_sentry_auth_token
from how2validate.validators.snyk.snyk_auth_key import validate_snyk_auth_key
Expand All @@ -16,6 +17,7 @@
from how2validate.utility.interface.validationResult import ValidationResult



# Create a dictionary that maps service names to their corresponding validator functions
service_handlers = {
"adafruit_io_key": validate_adafruit_io_key,
Expand All @@ -25,6 +27,7 @@
"hf_org_api_key": validate_hf_org_api_key,
"hf_user_access_token": validate_hf_user_access_token,
"npm_access_token": validate_npm_access_token,
"openai_api_key": validate_openai_api_key,
"pagerduty_api_key": validate_pagerduty_api_key,
"sentry_auth_token": validate_sentry_auth_token,
"snyk_auth_key": validate_snyk_auth_key,
Expand Down
112 changes: 112 additions & 0 deletions src/python/how2validate/validators/openai/openai_api_key.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import json
import logging
import requests
from how2validate.handler.email_handler import send_email
from how2validate.utility.interface.EmailResponse import EmailResponse
from how2validate.utility.interface.validationResult import ValidationProcess, ValidationResult
from how2validate.utility.tool_utility import handle_active_status, handle_inactive_status, handle_errors, response_validation

def validate_openai_api_key(provider: str, service: str, secret: str, response_flag: bool, report: str, is_browser: bool = True) -> ValidationResult:
"""
Validates the OpenAI API key by making a request to the OpenAI API.
Parameters:
- provider (str): The provider name (e.g., "OpenAI").
- service (str): The name of the service being validated.
- secret (str): The OpenAI API key to validate.
- response_flag (bool): Flag to indicate whether detailed response data should be returned.
- report (str): An optional email address to which a validation report should be sent.
- is_browser (bool): Indicates if the function is called from a browser environment (default is True).
Returns:
- ValidationResult: A structured response indicating the validation results.
"""
# Initialize the response structure as an instance of the ValidationProcess class
validation_response = ValidationProcess(
state="",
message="",
response=None,
report="[email protected]"
)

# OpenAI API endpoint for getting the organization details
url = "https://api.openai.com/v1/organizations"

# Headers to ensure no caching and to authorize the request using the provided API key (token)
nocache_headers = {'Cache-Control': 'no-cache'}
headers_map = {'Authorization': f'Bearer {secret}'}

try:
# Send a GET request to the OpenAI API with combined headers (nocache + authorization)
response_data = requests.get(url, headers={**nocache_headers, **headers_map})
# Raise an HTTPError if the response has an unsuccessful status code (4xx or 5xx)
response_data.raise_for_status()
# Check if the request was successful (HTTP 200)
if response_data.status_code == 200:
# If the token is valid, handle active status
active_response = handle_active_status(
provider,
service,
response_data,
response_flag,
report,
is_browser
)

validation_response.state = active_response.data.validate.state
validation_response.message = active_response.data.validate.message
validation_response.response = json.dumps(active_response.to_dict(), indent=4)

return response_validation(active_response, response_flag)

except requests.HTTPError as error:
if 400 <= error.response.status_code < 500:
# Handle inactive token or other statuses
inactive_response = handle_inactive_status(
provider,
service,
response_flag,
error,
report,
is_browser
)

validation_response.state = inactive_response.data.validate.state
validation_response.message = inactive_response.data.validate.message
validation_response.response = json.dumps(inactive_response.to_dict(), indent=4)

return response_validation(inactive_response, response_flag)

elif 500 <= error.response.status_code < 600:
# Handle server-side errors
error_response = handle_errors(
provider,
service,
response_flag,
report,
error,
is_browser
)

validation_response.state = error_response.data.validate.state
validation_response.message = error_response.data.validate.message
validation_response.response = json.dumps(error_response.to_dict(), indent=4)

return response_validation(error_response, response_flag)

finally:
# If a report email is provided, send the validation result via email
if report:
email_response = EmailResponse(
email=report,
provider=provider,
service=service,
state=validation_response.state,
message=validation_response.message,
response=validation_response.response,
)
try:
send_email(email_response)
logging.info('Validation report sent successfully')
except Exception as e:
logging.error('Error sending validation report', exc_info=True)
2 changes: 1 addition & 1 deletion src/python/tokenManager.json
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,7 @@
{
"secret_type": "openai_api_key",
"display_name": "Openai Api Key",
"is_enabled": false
"is_enabled": true
}
],
"Orbit": [
Expand Down

0 comments on commit 34376cf

Please sign in to comment.