BLT icon indicating copy to clipboard operation
BLT copied to clipboard

send a message to the #project-blt-bacon channel when a new claim is made on the claim portal. use the slack integration for the owasp-blt org

Open DonnieBLT opened this issue 9 months ago • 7 comments

DonnieBLT avatar Feb 28 '25 19:02 DonnieBLT

Which claim portal ? u are talking about here

igennova avatar Mar 01 '25 18:03 igennova

/assign

cicada0007 avatar Mar 04 '25 09:03 cicada0007

Hello @cicada0007! You've been assigned to OWASP-BLT/BLT issue #3754. You have 24 hours to complete a pull request.

github-actions[bot] avatar Mar 04 '25 09:03 github-actions[bot]

⏰ This issue has been automatically unassigned due to 24 hours of inactivity. The issue is now available for anyone to work on again.

github-actions[bot] avatar Mar 05 '25 10:03 github-actions[bot]

/assign

mahii-17 avatar Mar 22 '25 04:03 mahii-17

Hello @mahii-17! You've been assigned to OWASP-BLT/BLT issue #3754. You have 24 hours to complete a pull request.

github-actions[bot] avatar Mar 22 '25 04:03 github-actions[bot]

⏰ This issue has been automatically unassigned due to 24 hours of inactivity. The issue is now available for anyone to work on again.

github-actions[bot] avatar Mar 23 '25 06:03 github-actions[bot]

@coderabbitai what's the progress on this issue and what is being asked here? and check for conflicts with any PRs or overlapping issues if any.

Pritz395 avatar Dec 02 '25 09:12 Pritz395

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Fetch the issue details
echo "=== Issue #3754 Details ==="
gh issue view 3754 --json title,body,state,labels,assignees,createdAt,updatedAt,comments

echo -e "\n=== Related PRs ==="
# Search for PRs that mention this issue
gh pr list --search "3754" --state all --json number,title,state,author,createdAt --limit 10

echo -e "\n=== Related PRs (alternative search) ==="
# Also check if any PRs are linked to this issue
gh issue view 3754 --json closedByPullRequestsReferences

echo -e "\n=== Overlapping Issues (searching for 'claim' keyword) ==="
# Search for issues related to "claim" to find overlapping issues
gh issue list --search "claim in:title" --state open --json number,title,state,createdAt --limit 10

Length of output: 5203


🏁 Script executed:

#!/bin/bash

# Check details of PR #4030
echo "=== PR #4030 Details ==="
gh pr view 4030 --json title,state,isDraft,closedAt,mergedAt,comments,reviews,mergeable --comments 5

echo -e "\n=== PR #3806 Details ==="
gh pr view 3806 --json title,state,isDraft,closedAt,mergedAt,comments,reviews,mergeable --comments 5

echo -e "\n=== Searching for 'claim portal' references in codebase ==="
# Search for existing claim portal implementations
rg -i "claim.?portal" --type py --type js -n -C 2 | head -50

echo -e "\n=== Searching for bacon claim functionality ==="
rg -i "bacon.*claim|claim.*bacon" --type py --type js -n -C 2 | head -50

echo -e "\n=== Searching for Slack integration references ==="
rg -i "slack" --type py --type js -n -C 2 | head -50

Length of output: 3225


🏁 Script executed:

#!/bin/bash

# Check details of PR #4030 with correct syntax
echo "=== PR #4030 Details ==="
gh pr view 4030 --json title,state,isDraft,closedAt,mergedAt,body,labels

echo -e "\n=== PR #3806 Details ==="
gh pr view 3806 --json title,state,isDraft,closedAt,mergedAt,body,labels

echo -e "\n=== Searching for 'bacon' references in the codebase ==="
rg -i "bacon" --type py -n -C 2 | head -80

echo -e "\n=== Searching for claim-related models and views ==="
rg -i "class.*claim" --type py -n -C 3 | head -60

echo -e "\n=== Check if there are any bacon-related models ==="
fd -e py -x grep -l "bacon" {} \;

Length of output: 12697


🏁 Script executed:

#!/bin/bash

# Search for BaconSubmission model and related views
echo "=== BaconSubmission Model and Views ==="
rg "BaconSubmission" --type py -n -C 5

echo -e "\n=== Check for bacon claim submission views ==="
rg "def.*submit|class.*Submit" --type py -n -C 3 | grep -i bacon -A 5 -B 5

echo -e "\n=== Check migration 0209 for BaconSubmission ==="
cat website/migrations/0209_baconsubmission.py 2>/dev/null || echo "File not found or not accessible"

echo -e "\n=== List all bacon-related files ==="
fd -e py | xargs grep -l "BaconSubmission" 2>/dev/null

Length of output: 15048


@Pritz395 Based on my analysis, here's the complete picture:

📋 What's Being Asked

Issue #3754 requests adding Slack notifications to the #project-blt-bacon channel whenever a user submits a new BACON token claim through the claim portal.

The "claim portal" (which confused @igennova) refers to the BaconSubmission system where users can claim BACON tokens for their contributions:

  • Endpoint: /api/bacon/submit/
  • View: BaconSubmissionView in website/views/bitcoin.py (line 84)
  • Users submit GitHub PR URLs with contribution details to claim BACON rewards

📊 Progress Status

Current State: Issue is OPEN and available to work on

History:

  1. Assigned twice, both contributors unassigned due to 24-hour inactivity:

    • @cicada0007 (Mar 4, 2025)
    • @mahii-17 (Mar 22, 2025)
  2. Two PRs attempted to fix it but both were CLOSED (not merged):

    • PR #4030 by @mahii-17 - Most relevant attempt
      • Added Slack integration using slack_sdk.WebClient
      • Sent messages to #project-blt-bacon on new bacon claims
      • Closed on April 5, 2025 without merging
    • PR #3806 by @cicada0007 - Less relevant
      • Focused on bug report alerts, not bacon claims
      • Also claimed to close #3754 but addressed wrong feature
      • Closed on March 5, 2025

🔍 Conflicts & Overlapping Issues

No conflicts found:

  • No currently active PRs working on this issue
  • No overlapping open issues with similar requirements
  • Slack integration infrastructure already exists in website/views/slackbot.py
  • Ready for a fresh implementation attempt

💡 Recommendation

The issue is clear and ready to be worked on. A contributor would need to:

  1. Add Slack notification logic to BaconSubmissionView.post() method
  2. Use existing Slack integration (SLACK_BOT_TOKEN from environment)
  3. Send message to #project-blt-bacon channel with claim details
  4. Reference PR #4030 for implementation approach (though don't copy directly)

Would you like me to help assign this to someone or create a more detailed implementation plan?

coderabbitai[bot] avatar Dec 02 '25 10:12 coderabbitai[bot]

@coderabbitai the maintainer specifically mentioned "we want this to be database driven, the org already has the connection to slack through integrations". Give me the workflow of what needs to be done for this issue to be resolved.

Pritz395 avatar Dec 02 '25 10:12 Pritz395

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Get all comments on issue #3754 to find maintainer's comment
echo "=== All Comments on Issue #3754 ==="
gh issue view 3754 --json comments --jq '.comments[] | "Author: \(.author.login)\nDate: \(.createdAt)\nBody: \(.body)\n---"'

echo -e "\n=== Search for Integration models ==="
rg "class.*Integration" --type py -n -C 5

echo -e "\n=== Search for Slack integration in models ==="
rg -i "slack.*integration|integration.*slack" --type py -n -C 3

echo -e "\n=== Search for notification or alert systems ==="
rg "def.*notify|class.*Notification|def.*send_alert" --type py -n -C 3 | head -100

echo -e "\n=== Check for Integration usage with BaconSubmission ==="
rg "Integration" --type py -n -C 3 | grep -i "bacon\|notification\|slack" -A 3 -B 3

Length of output: 62603


🏁 Script executed:

#!/bin/bash

# Get PR #4030 comments to find maintainer feedback
echo "=== PR #4030 Comments ==="
gh pr view 4030 --json comments --jq '.comments[] | "Author: \(.author.login)\nDate: \(.createdAt)\nBody: \(.body)\n---"'

echo -e "\n=== Check BaconSubmissionView implementation ==="
cat website/views/bitcoin.py | grep -A 50 "class BaconSubmissionView"

echo -e "\n=== Find OWASP BLT organization references ==="
rg "OWASP.?BLT" --type py -n -C 2

Length of output: 49598


@Pritz395 Perfect! I found the maintainer's feedback. Here's the complete workflow for implementing this database-driven Slack notification system:


🔄 Implementation Workflow for Issue #3754

Context: Why "Database-Driven"?

The maintainer rejected previous PRs because they used the SLACK_BOT_TOKEN environment variable directly. Instead, the codebase has an Integration system where organizations configure their Slack connections through the UI, and the tokens are stored in the database.


📋 Step-by-Step Implementation

Step 1: Understand the Database Models

Located in website/models.py:

# Organization (line 72-80)
class Organization(models.Model):
    name = models.CharField(max_length=255)
    # ... other fields

# Integration (line 87-102)  
class Integration(models.Model):
    organization = models.ForeignKey(Organization)
    service_name = models.CharField()  # e.g., "slack"

# SlackIntegration (line 105-126)
class SlackIntegration(models.Model):
    integration = models.OneToOneField(Integration)
    bot_access_token = models.CharField()  # Bot token stored here
    workspace_name = models.CharField()
    default_channel_id = models.CharField()  # Channel ID to post to
    default_channel_name = models.CharField()  # e.g., "project-blt-bacon"

Step 2: Locate the Target Code

File: website/views/bitcoin.py
Class: BaconSubmissionView (starting at line 84)
Method: post() method (lines 85-130)

Current behavior: Creates a BaconSubmission record, returns JSON response. No Slack notification.


Step 3: Follow Existing Patterns

The codebase already has 3 working examples of database-driven Slack:

Example 1: website/utils.py (lines 886-900)

def send_tweet_to_slack(...):
    from website.models import Organization, SlackIntegration
    
    # 1. Find OWASP BLT organization
    owasp_org = Organization.objects.filter(name__icontains="OWASP BLT").first()
    
    # 2. Get its Slack integration
    slack_integration = SlackIntegration.objects.filter(
        integration__organization=owasp_org
    ).first()
    
    # 3. Use token and channel from database
    bot_token = slack_integration.bot_access_token
    channel_id = slack_integration.default_channel_id
    
    # 4. Send message using slack_sdk
    from slack_sdk import WebClient
    client = WebClient(token=bot_token)
    client.chat_postMessage(channel=channel_id, text=message)

Example 2: blt/mail.py (lines 54-74) - Similar pattern

Example 3: website/management/commands/slack_daily_timelogs.py (lines 19-23) - Iterates over all SlackIntegrations


Step 4: Implementation Steps

Location: website/views/bitcoin.pyBaconSubmissionView.post() method

After line 128 (after submission = BaconSubmission.objects.create(...)), add:

# Step A: Import required modules
from website.models import Organization, SlackIntegration
from slack_sdk import WebClient
import logging

logger = logging.getLogger(__name__)

# Step B: Query the database for OWASP BLT's Slack integration
try:
    owasp_org = Organization.objects.filter(name__icontains="OWASP BLT").first()
    
    if owasp_org:
        slack_integration = SlackIntegration.objects.filter(
            integration__organization=owasp_org
        ).first()
        
        if slack_integration and slack_integration.bot_access_token:
            # Step C: Get credentials from database
            bot_token = slack_integration.bot_access_token
            
            # Use default channel or find #project-blt-bacon specifically
            channel_id = slack_integration.default_channel_id
            
            # Step D: Build the message
            message = (
                f"🥓 *New BACON Claim Submitted!*\n\n"
                f"• *User:* {request.user.username}\n"
                f"• *Type:* {contribution_type}\n"
                f"• *PR:* {github_url}\n"
                f"• *Description:* {description}\n"
                f"• *Amount:* {bacon_amount} BACON\n"
                f"• *Status:* {status}"
            )
            
            # Step E: Send to Slack
            client = WebClient(token=bot_token)
            client.chat_postMessage(
                channel=channel_id,
                text=message,
                unfurl_links=False
            )
            
            logger.info(f"Slack notification sent for submission {submission.id}")
        else:
            logger.warning("Slack integration not configured for OWASP BLT")
    else:
        logger.warning("OWASP BLT organization not found")
        
except Exception as e:
    # Don't fail the submission if Slack fails
    logger.error(f"Failed to send Slack notification: {e}")

Step 5: Handle Channel Configuration

The default_channel_id might not be set to #project-blt-bacon. You have two options:

Option A: Use whatever channel is configured as default (simpler)

Option B: Search for #project-blt-bacon specifically:

# If default_channel_id is not set, try to find #project-blt-bacon
if not channel_id:
    client = WebClient(token=bot_token)
    channels = client.conversations_list(types="public_channel")
    for channel in channels['channels']:
        if channel['name'] == 'project-blt-bacon':
            channel_id = channel['id']
            break

Step 6: Testing Considerations

  1. Database Setup: Ensure OWASP BLT organization exists with Slack integration configured
  2. Channel Exists: Verify #project-blt-bacon channel exists in the workspace
  3. Bot Permissions: Bot must have chat:write scope and be invited to the channel
  4. Error Handling: Slack failure should NOT fail the bacon submission

Step 7: Files to Modify

File Changes
website/views/bitcoin.py Add Slack notification logic after BaconSubmission.objects.create()
(Optional) Tests Add test for Slack notification (mock WebClient)

🎯 Key Differences from Failed PRs

PR #4030 Approach Correct Database-Driven Approach
Used SLACK_BOT_TOKEN env var Query SlackIntegration.bot_access_token from database
Hardcoded channel mapping Use SlackIntegration.default_channel_id
Not organization-aware Filters by organization (OWASP BLT)
Direct Slack SDK usage Follows existing pattern from website/utils.py

📦 Required Dependencies

Already in the codebase:

  • slack-sdk (imported in existing code)
  • SlackIntegration model
  • ✅ Slack OAuth flow for setup

🔐 Configuration Requirements

Before the code works, admins must:

  1. Navigate to Organization Dashboard → Integrations
  2. Connect Slack via OAuth (AddSlackIntegrationView)
  3. Select #project-blt-bacon as the default channel
  4. Save configuration

Database will then have:

  • Integration record with service_name='slack' and organization=OWASP BLT
  • SlackIntegration record with bot_access_token and default_channel_id

✅ Success Criteria

  1. When a user submits a BACON claim via /api/bacon/submit/
  2. The submission is created successfully
  3. A Slack notification is sent to #project-blt-bacon channel
  4. Message includes: username, contribution type, PR link, description, amount
  5. If Slack fails, the submission still succeeds (graceful degradation)

Would you like me to generate the actual code changes using the `` tag, or would you prefer to assign this to a contributor with these detailed instructions?


⏳ Preparing changes...

coderabbitai[bot] avatar Dec 02 '25 10:12 coderabbitai[bot]

/assign

Pritz395 avatar Dec 02 '25 10:12 Pritz395

Hello @Pritz395! You've been assigned to OWASP-BLT/BLT issue #3754. You have 24 hours to complete a pull request.


This comment was generated by OWASP BLT-Action

github-actions[bot] avatar Dec 02 '25 10:12 github-actions[bot]