Skip to content

Commit

Permalink
feat(Github): Github Personal Access Token added
Browse files Browse the repository at this point in the history
  • Loading branch information
Vigneshkna committed Nov 19, 2024
1 parent 268c702 commit be505cb
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/js/how2validate/handler/validator_handler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { validateAdafruitIOKey } from "../validators/adafruit/adafruit_io_key.js"; // Import the Adafruit token validator
import { validateAivenAuthToken } from "../validators/aiven/aiven_auth_token.js"; // Import the Aiven API key validator
import { validateAnthropicAPIKey } from "../validators/anthropic/anthropic_api_key.js"; // Import the Anthropic API Key validator
import { validateGitHubPersonalAccessToken } from "../validators/github/github_personal_access_token.js"; // Import the GitHub Personal Access Token validator
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
Expand Down Expand Up @@ -46,6 +47,7 @@ const serviceHandlers: Record<string, ValidatorFunction> = {
adafruit_io_key: validateAdafruitIOKey, // Adafruit Io Key validator
aiven_auth_token: validateAivenAuthToken, // Aiven Auth token
anthropic_api_key: validateAnthropicAPIKey, // Anthropic API Key
github_personal_access_token: validateGitHubPersonalAccessToken, // GitHub Personal Access Token
hf_org_api_key: validateHFOrgApiKey, // HuggingFace API Key
hf_user_access_token: validateHFUserAccessToken, // HuggingFace API Key
npm_access_token: validateNpmAccessToken, // NPM access token validator
Expand Down
121 changes: 121 additions & 0 deletions src/js/how2validate/validators/github/github_personal_access_token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/**
* @module GitHubPersonalAccessTokenValidator
* @description
* This module provides functionality to validate a GitHub Personal Access Token by making an API call to the GitHub service.
* It returns a validation status, processes the response from the API, and optionally sends an email report with the results.
*
* @requires axios - Used for making HTTP requests to the GitHub 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 validateGitHubPersonalAccessToken
* @description
* Validates a GitHub Personal Access Token by making an API call to the GitHub API.
* Checks the token's validity, handles errors, and returns a validation result.
* Optionally sends an email summarizing the validation results.
*
* @async
* @param {string} provider - The provider name (e.g., "GitHub").
* @param {string} service - The name of the service being validated.
* @param {string} secret - The GitHub Personal Access Token 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 true).
*
* @returns {Promise<ValidationResult>} - A promise that resolves to a `ValidationResult` object containing the validation result.
*/
export async function validateGitHubPersonalAccessToken(
provider: string,
service: string,
secret: string,
responseFlag: boolean,
report: string,
isBrowser: boolean = true
): Promise<ValidationResult> {
const validationResponse = {} as SecretStatusMessage;
const url = "https://api.github.com/user";
const nocacheHeaders = { "Cache-Control": "no-cache" };
const headers = { Authorization: `Bearer ${secret}` };

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

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

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

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

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

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

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

return responseValidation(errResponse, responseFlag);
} finally {
if (report) {
const emailResponse: EmailResponse = {
provider: provider,
service: service,
state: validationResponse.state,
message: validationResponse.message,
response: validationResponse.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 @@ -704,7 +704,7 @@
{
"secret_type": "github_personal_access_token",
"display_name": "Github Personal Access Token",
"is_enabled": false
"is_enabled": true
},
{
"secret_type": "github_refresh_token",
Expand Down
2 changes: 2 additions & 0 deletions src/python/how2validate/handler/validator_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from how2validate.validators.adafruit.adafruit_io_key import validate_adafruit_io_key
from how2validate.validators.aiven.aiven_auth_token import validate_aiven_auth_token
from how2validate.validators.anthropic.anthropic_api_key import validate_anthropic_api_key
from how2validate.validators.github.github_personal_access_token import validate_github_personal_access_token
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
Expand All @@ -20,6 +21,7 @@
"adafruit_io_key": validate_adafruit_io_key,
"aiven_auth_token": validate_aiven_auth_token,
"anthropic_api_key": validate_anthropic_api_key,
"github_personal_access_token": validate_github_personal_access_token,
"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,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
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_github_personal_access_token(
provider: str,
service: str,
secret: str,
response_flag: bool,
report: str,
is_browser: bool = True
) -> ValidationResult:
"""
Validates a GitHub personal access token by making a request to the GitHub API.
Parameters:
- provider (str): The provider name (e.g., "GitHub").
- service (str): The name of the service being validated.
- secret (str): The GitHub personal access token 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]"
)

# GitHub API endpoint for validating a personal access token
url = "https://api.github.com/user"

# Headers for the API request
nocache_headers = {'Cache-Control': 'no-cache'}
headers = {'Authorization': f'Bearer {secret}'}

try:
# Send a GET request to the GitHub API
response_data = requests.get(url, headers={**nocache_headers, **headers})
# Raise an error for unsuccessful HTTP status codes
response_data.raise_for_status()

# Handle successful response (HTTP 200)
if response_data.status_code == 200:
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:
# Handle 4xx client errors
if 400 <= error.response.status_code < 500:
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)

# Handle 5xx server errors
elif 500 <= error.response.status_code < 600:
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:
# Send the validation result via email if a report email is provided
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 @@ -704,7 +704,7 @@
{
"secret_type": "github_personal_access_token",
"display_name": "Github Personal Access Token",
"is_enabled": false
"is_enabled": true
},
{
"secret_type": "github_refresh_token",
Expand Down

0 comments on commit be505cb

Please sign in to comment.