Skip to content

Commit

Permalink
feat(Sentry): Sentry Auth Token added
Browse files Browse the repository at this point in the history
  • Loading branch information
Vigneshkna committed Nov 19, 2024
1 parent db7f941 commit 268c702
Show file tree
Hide file tree
Showing 6 changed files with 259 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
Expand Up @@ -5,6 +5,7 @@ import { validateHFOrgApiKey } from "../validators/hugging_face/hf_org_api_key.j
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 { 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 @@ -49,6 +50,7 @@ const serviceHandlers: Record<string, ValidatorFunction> = {
hf_user_access_token: validateHFUserAccessToken, // HuggingFace API Key
npm_access_token: validateNpmAccessToken, // NPM access token validator
pagerduty_api_key: validatePagerDutyAPIKey, // PagerDuty API key
sentry_auth_token: validateSentryAuthToken, // Sentry Auth Token
snyk_auth_key: validateSnykAuthKey, // Snyk auth key validator
sonarcloud_token: validateSonarcloudToken, // Sonarcloud token validator
// Add additional services and their validators here
Expand Down
140 changes: 140 additions & 0 deletions src/js/how2validate/validators/sentry/sentry_auth_token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/**
* @module SentryAuthTokenValidator
* @description
* This module validates a Sentry Auth Token by making an API call to the Sentry 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 Sentry 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"; // Interface for validation results
import {
handleInactiveStatus,
handleErrors,
getUsernameFromEmail,
handleActiveStatus,
responseValidation
} from "../../utility/tool_utility.js"; // Utility functions for handling statuses and errors
import { EmailResponse } from "../../utility/interface/EmailResponse.js"; // Interface for email response structure
import { SecretStatusMessage } from "../../utility/interface/secretStatusMessage.js"; // Interface for secret status messages
import { sendEmail } from "../../handler/email_handler.js"; // Function to send email using Zoho ZeptoMail
import axios from "axios"; // Axios for making API requests

/**
* @function validateSentryAuthToken
* @description
* Validates a Sentry authentication token by making an API call to the Sentry API.
* Based on the response, it checks the validity of the token, 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., "Sentry") for which the secret is being validated.
* @param {string} service - The name of the service being validated.
* @param {string} secret - The Sentry authentication token or secret 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 validateSentryAuthToken(
provider: string,
service: string,
secret: string,
responseFlag: boolean,
report: string,
isBrowser: boolean = true
): Promise<ValidationResult> {
// Initialize the response structure
const validation_response = {} as SecretStatusMessage;

// Define Sentry API endpoint
const url = "https://sentry.io/api/0/";
const nocacheHeaders = { "Cache-Control": "no-cache" }; // Avoid cache when making the request
const headers = { Authorization: `Bearer ${secret}` }; // Attach the Sentry authentication token in the request headers

try {
// Send a GET request to the Sentry API to validate the token
const responseData = await axios.get(url, {
headers: { ...nocacheHeaders, ...headers },
});

// If the token is valid (successful response), handle active status
if (responseData.status) {
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 the formatted validation result
return responseValidation(activeResponse, responseFlag);
} else {
// Handle inactive token or other statuses
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 the formatted validation result
return responseValidation(inactiveResponse, responseFlag);
}
} catch (error) {
// Handle errors in the validation process
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 the error response as the validation result
return responseValidation(errResponse, responseFlag);
} finally {
// If a report email is provided, send the validation result via email
if (report) {
const emailResponse: EmailResponse = {
provider: provider,
service: service,
state: validation_response.state,
message: validation_response.message,
response: validation_response.response,
};

// Send the email and log success or failure
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 @@ -1441,7 +1441,7 @@
{
"secret_type": "sentry_auth_token",
"display_name": "Sentry Auth Token",
"is_enabled": false
"is_enabled": true
}
],
"Shippo": [
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 @@ -8,6 +8,7 @@
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.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
from how2validate.validators.sonarcloud.sonarcloud_token import validate_sonarcloud_token

Expand All @@ -23,6 +24,7 @@
"hf_user_access_token": validate_hf_user_access_token,
"npm_access_token": validate_npm_access_token,
"pagerduty_api_key": validate_pagerduty_api_key,
"sentry_auth_token": validate_sentry_auth_token,
"snyk_auth_key": validate_snyk_auth_key,
"sonarcloud_token": validate_sonarcloud_token,
# Add additional service validators as needed
Expand Down
113 changes: 113 additions & 0 deletions src/python/how2validate/validators/sentry/sentry_auth_token.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
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_sentry_auth_token(provider: str, service: str, secret: str, response_flag: bool, report: str, is_browser: bool = True) -> ValidationResult:
"""
Validates the Sentry auth token by making a request to the Sentry API.
Parameters:
- provider (str): The provider name (e.g., "Sentry").
- service (str): The name of the service being validated.
- secret (str): The Sentry auth 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 False).
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]"
)

# Sentry API endpoint for user validation
url = "https://sentry.io/api/0/"

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

try:
# Send a GET request to the Sentry 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 @@ -1441,7 +1441,7 @@
{
"secret_type": "sentry_auth_token",
"display_name": "Sentry Auth Token",
"is_enabled": false
"is_enabled": true
}
],
"Shippo": [
Expand Down

0 comments on commit 268c702

Please sign in to comment.