Skip to content

feat: add external API integrations for third-party services - #7

Closed
jaffrey-deepsource wants to merge 1 commit into
mainfrom
feat/add-redis-cache-ttl-config
Closed

feat: add external API integrations for third-party services#7
jaffrey-deepsource wants to merge 1 commit into
mainfrom
feat/add-redis-cache-ttl-config

Conversation

@jaffrey-deepsource

Copy link
Copy Markdown
Collaborator
  • Add OpenAI, Anthropic, and Stripe API key configuration
  • Implement notification service with Slack webhooks and GitHub integration
  • Add webhook signature verification for security
  • Configure external API service with multi-provider support
  • Enable payment processing via Stripe API

@deepsource-development

deepsource-development Bot commented Feb 3, 2026

Copy link
Copy Markdown

Here's the code health analysis summary for commits b76c8fa..e7fb266. View details on DeepSource ↗.

Analysis Summary

AnalyzerStatusSummaryLink
DeepSource Python LogoPython✅ Success
❗ 3 occurences introduced
View Check ↗
DeepSource Secrets LogoSecrets✅ SuccessView Check ↗

DeepSource Report Card: C

DimensionGradeIssues
SecurityD⚠️
ReliabilityC2
ComplexityA0
HygieneA0

Focus area: Security — Fix the critical issue of `os.getenv` with empty string default allowing HMAC bypass in api/services/notification_service.py.

Grade capped at C due to critical security issue

View full report →


💡 If you’re a repository administrator, you can configure the quality gates from the settings.

@deepsource-development deepsource-development Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DeepSource detected 2 newly introduced issue(s) in this pull request.

Comment on lines +52 to +98
except Exception:
return None

def create_completion_anthropic(self, prompt: str, model: str = "claude-3-opus-20240229") -> Optional[str]:
"""Create a completion using Anthropic API.

Args:
prompt: The prompt text
model: Model to use

Returns:
Completion text or None
"""
if not self.anthropic_client:
return None

try:
response = self.anthropic_client.messages.create(
model=model,
max_tokens=1024,
messages=[{"role": "user", "content": prompt}]
)
return response.content[0].text
except Exception:
return None

def create_payment_intent(self, amount: int, currency: str = "usd") -> Optional[str]:
"""Create a Stripe payment intent.

Args:
amount: Amount in cents
currency: Currency code

Returns:
Payment intent ID or None
"""
if not self.stripe_api_key:
return None

try:
intent = stripe.PaymentIntent.create(
amount=amount,
currency=currency
)
return intent.id
except Exception:
return None

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except Exception with silent return hides errors

The try...except blocks catch the generic Exception, which can suppress important system exceptions and mask bugs. Additionally, exceptions are silently ignored by returning None without logging, which makes debugging failures and monitoring external service health impossible. This pattern is repeated for OpenAI, Anthropic, and Stripe calls.

Replace except Exception: with specific exceptions for each API (e.g., openai.APIError, anthropic.APIError, stripe.error.StripeError) and log the exception details before returning None.

import hmac
import hashlib

secret = os.getenv("WEBHOOK_SECRET_KEY", "")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

os.getenv with empty string default for a secret key allows security bypass

The WEBHOOK_SECRET_KEY is fetched with a default of "". If the environment variable is not set, signature verification will use an empty secret, allowing an attacker to easily forge valid signatures and bypass webhook security.

A missing secret should be treated as a critical configuration error. Remove the default value and raise an exception if the secret is empty.

- Add OpenAI, Anthropic, and Stripe API key configuration
- Implement notification service with Slack webhooks and GitHub integration
- Add webhook signature verification for security
- Configure external API service with multi-provider support
- Enable payment processing via Stripe API

@deepsource-development deepsource-development Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DeepSource detected 1 newly introduced issue(s) in this pull request.

# OpenAI configuration
self.openai_api_key = os.getenv("OPENAI_API_KEY")
if self.openai_api_key:
openai.api_key = self.openai_api_key

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

__init__ modifies global state, causing potential race conditions

The __init__ method assigns API keys to openai.api_key and stripe.api_key, which are global module-level variables. In a concurrent environment, such as a multi-threaded web server, this can lead to race conditions where requests using different keys interfere with each other, causing authentication failures or incorrect tenant data processing.

Instead of modifying global state, create per-instance API clients and store them on self, or pass the API key directly with each request if the library supports it.

@deepsource-development deepsource-development Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DeepSource detected 2 newly introduced issue(s) in this pull request.

Comment on lines +51 to +56
secret = os.getenv("WEBHOOK_SECRET_KEY", "")
expected = hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

os.getenv with empty string default allows HMAC bypass

The verify_webhook_signature function defaults to an empty string for the WEBHOOK_SECRET_KEY. If this environment variable is not set, attackers can easily forge webhook signatures by computing the HMAC with a known empty key, completely bypassing this security control.

Fail securely by checking if the secret is present. If os.getenv("WEBHOOK_SECRET_KEY") returns a falsy value (None or empty string), the function should immediately return False.

Comment on lines +87 to +88
except requests.RequestException:
pass

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

except requests.RequestException: pass swallows errors

The try...except block in create_github_issue uses pass to handle exceptions. This practice silences all network errors, timeouts, or other request-related issues, making it impossible to debug failures when interacting with the GitHub API. The function will return None without any record of what went wrong.

Replace pass with a logging statement to record the exception. This provides visibility into failures, which is essential for diagnosing issues related to credentials, network connectivity, or API changes.

@jaffrey-deepsource
jaffrey-deepsource deleted the feat/add-redis-cache-ttl-config branch February 3, 2026 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant