Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .aislop/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
version: 1
engines:
# CI already runs rustfmt, clippy, and the compiler matrix.
format: false
lint: false
code-quality: true
ai-slop: true
architecture: true
security: true
quality:
maxFunctionLoc: 80
maxFileLoc: 400
maxNesting: 5
maxParams: 6
lint:
typecheck: false
expoDoctor: false
security:
audit: true
auditTimeout: 25000
scoring:
weights:
format: 0.3
lint: 0.6
code-quality: 0.8
ai-slop: 1
architecture: 1
security: 1.5
thresholds:
good: 75
ok: 50
smoothing: 5
maxPerRule: 40
ci:
failBelow: 85
format: json
telemetry:
enabled: true
8 changes: 8 additions & 0 deletions .aislop/rules.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Keep credential storage behind the authentication layer.
# CLI modules should use the auth service rather than importing keyring directly.
rules:
- name: no-keyring-outside-auth
type: forbid_import
from: "src/cli/**"
match: "keyring"
severity: error
2 changes: 2 additions & 0 deletions .aislopignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Synthetic credentials are test-only fixtures included by the unit-test crate.
tests/fixtures/aislop_tokens.rs
15 changes: 15 additions & 0 deletions .github/workflows/aislop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: aislop

on:
push:
branches: [main]
pull_request:

jobs:
quality-gate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: scanaislop/aislop@v1
with:
version: 0.16.1
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@ run-ralph-loop.sh
/.claude
/.codex
/.pi
/.aislop
/.aislop/*
!/.aislop/config.yml
!/.aislop/rules.yml
16 changes: 7 additions & 9 deletions src/api/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,7 @@ mod tests {
match token_type {
TokenType::UserOAuth => TokenSet {
token_type: TokenType::UserOAuth,
access_token: "xoxp-123456789-0123456789-abcdef".to_string(),
access_token: crate::test_fixtures::USER_OAUTH.to_string(),
xoxd_cookie: None,
team_id: "T12345".to_string(),
team_name: "Test".to_string(),
Expand All @@ -593,7 +593,7 @@ mod tests {
},
TokenType::BotOAuth => TokenSet {
token_type: TokenType::BotOAuth,
access_token: "xoxb-123456789-0123456789-abcdef".to_string(),
access_token: crate::test_fixtures::BOT_OAUTH.to_string(),
xoxd_cookie: None,
team_id: "T12345".to_string(),
team_name: "Test".to_string(),
Expand All @@ -604,7 +604,7 @@ mod tests {
},
TokenType::Browser => TokenSet {
token_type: TokenType::Browser,
access_token: "xoxc-123456789-0123456789-abcdef".to_string(),
access_token: crate::test_fixtures::BROWSER.to_string(),
xoxd_cookie: Some("xoxd-test-cookie".to_string()),
team_id: "T12345".to_string(),
team_name: "Test".to_string(),
Expand Down Expand Up @@ -812,8 +812,6 @@ mod tests {
assert!(client.base_url().contains("slack.com") || client.base_url().starts_with("http"));
}

// --- normalize_api_endpoint / api_request validation -------------------

#[test]
fn test_normalize_endpoint_bare_method_names() {
for m in [
Expand Down Expand Up @@ -874,10 +872,10 @@ mod tests {
"ftp://slack.com/api/auth.test",
"file:///etc/passwd",
// Wrong host / lookalikes
"https://evil.com/api/auth.test",
"https://slack.com.evil.com/api/auth.test",
"https://evil.com/api/auth.test", // aislop-ignore-line ai-slop/hardcoded-url -- invalid-host validation fixture
"https://slack.com.evil.com/api/auth.test", // aislop-ignore-line ai-slop/hardcoded-url -- lookalike-host validation fixture
"https://api.slack.com/api/auth.test",
"https://slack.com@evil.com/api/auth.test",
"https://slack.com@evil.com/api/auth.test", // aislop-ignore-line ai-slop/hardcoded-url -- userinfo validation fixture
// Userinfo
"https://user:pass@slack.com/api/auth.test",
"https://user@slack.com/api/auth.test",
Expand Down Expand Up @@ -914,7 +912,7 @@ mod tests {
let client = SlackClient::with_base_url(token, "http://127.0.0.1:1".to_string()).unwrap();
let err = client
.api_request(
"https://evil.com/api/auth.test",
"https://evil.com/api/auth.test", // aislop-ignore-line ai-slop/hardcoded-url -- invalid-host validation fixture
reqwest::Method::GET,
&serde_json::Value::Null,
)
Expand Down
4 changes: 2 additions & 2 deletions src/api/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ mod tests {
fn create_browser_token() -> TokenSet {
TokenSet {
token_type: TokenType::Browser,
access_token: "xoxc-1234567890-0123456789-abcdefghij".to_string(),
access_token: crate::test_fixtures::BROWSER.to_string(),
xoxd_cookie: Some("xoxd-test-cookie-value".to_string()),
team_id: "T12345".to_string(),
team_name: "Test Team".to_string(),
Expand All @@ -337,7 +337,7 @@ mod tests {
fn create_oauth_token() -> TokenSet {
TokenSet {
token_type: TokenType::UserOAuth,
access_token: "xoxp-1234567890-0123456789-abcdefghij".to_string(),
access_token: crate::test_fixtures::USER_OAUTH.to_string(),
xoxd_cookie: None,
team_id: "T12345".to_string(),
team_name: "Test Team".to_string(),
Expand Down
40 changes: 0 additions & 40 deletions src/api/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ use super::types::{
/// Maximum file download size (5MB)
const MAX_FILE_SIZE: u64 = 5 * 1024 * 1024;

// ============================================================================
// Auth Methods
// ============================================================================

impl SlackClient {
/// Test authentication and get information about the token
///
Expand All @@ -36,10 +32,6 @@ impl SlackClient {
}
}

// ============================================================================
// Conversations Methods
// ============================================================================

/// Parameters for conversations.list
#[derive(Debug, Serialize, Default)]
pub struct ConversationsListParams {
Expand Down Expand Up @@ -367,10 +359,6 @@ impl SlackClient {
}
}

// ============================================================================
// Chat Methods
// ============================================================================

/// Parameters for chat.postMessage
#[derive(Debug, Serialize)]
pub struct ChatPostMessageParams {
Expand Down Expand Up @@ -441,10 +429,6 @@ impl SlackClient {
}
}

// ============================================================================
// Search Methods
// ============================================================================

/// Parameters for search.messages
#[derive(Debug, Serialize)]
pub struct SearchMessagesParams {
Expand Down Expand Up @@ -505,10 +489,6 @@ impl SlackClient {
}
}

// ============================================================================
// Users Methods
// ============================================================================

impl SlackClient {
/// List all users in the workspace
///
Expand Down Expand Up @@ -562,10 +542,6 @@ impl SlackClient {
}
}

// ============================================================================
// Reactions Methods
// ============================================================================

impl SlackClient {
/// Add a reaction to a message
///
Expand Down Expand Up @@ -618,10 +594,6 @@ impl SlackClient {
}
}

// ============================================================================
// Files Methods
// ============================================================================

impl SlackClient {
/// Get information about a file
///
Expand Down Expand Up @@ -700,10 +672,6 @@ impl SlackClient {
}
}

// ============================================================================
// Reactions Get Method
// ============================================================================

impl SlackClient {
/// Get reactions for a message
///
Expand Down Expand Up @@ -731,10 +699,6 @@ impl SlackClient {
}
}

// ============================================================================
// Reminders Methods
// ============================================================================

impl SlackClient {
/// List reminders
///
Expand Down Expand Up @@ -802,10 +766,6 @@ impl SlackClient {
}
}

// ============================================================================
// Status/Presence Methods
// ============================================================================

impl SlackClient {
/// Get the current user's profile
///
Expand Down
39 changes: 18 additions & 21 deletions src/auth/browser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ mod tests {
#[test]
fn test_browser_tokens_valid() {
let tokens = BrowserTokens::new(
"xoxc-1234567890-abcdef123456789012345678901234567890".into(),
"xoxd-abcdefghijklmnopqrstuvwxyz1234567890".into(),
crate::test_fixtures::BROWSER_LONG.into(),
crate::test_fixtures::BROWSER_COOKIE.into(),
);

assert!(tokens.validate().is_ok());
Expand All @@ -179,8 +179,8 @@ mod tests {
#[test]
fn test_browser_tokens_invalid_xoxc_prefix() {
let tokens = BrowserTokens::new(
"xoxp-1234567890-abcdef123456789012345678901234567890".into(),
"xoxd-abcdefghijklmnopqrstuvwxyz1234567890".into(),
crate::test_fixtures::INVALID_BROWSER_PREFIX.into(),
crate::test_fixtures::BROWSER_COOKIE.into(),
);

let result = tokens.validate();
Expand All @@ -191,8 +191,8 @@ mod tests {
#[test]
fn test_browser_tokens_xoxc_too_short() {
let tokens = BrowserTokens::new(
"xoxc-123".into(),
"xoxd-abcdefghijklmnopqrstuvwxyz1234567890".into(),
crate::test_fixtures::SHORT_BROWSER.into(),
crate::test_fixtures::BROWSER_COOKIE.into(),
);

let result = tokens.validate();
Expand All @@ -202,8 +202,8 @@ mod tests {
#[test]
fn test_browser_tokens_xoxc_invalid_chars() {
let tokens = BrowserTokens::new(
"xoxc-1234567890-abcdef!@#$%^&*()".into(),
"xoxd-abcdefghijklmnopqrstuvwxyz1234567890".into(),
crate::test_fixtures::INVALID_BROWSER_CHARS.into(),
crate::test_fixtures::BROWSER_COOKIE.into(),
);

let result = tokens.validate();
Expand All @@ -212,10 +212,7 @@ mod tests {

#[test]
fn test_browser_tokens_empty_xoxd() {
let tokens = BrowserTokens::new(
"xoxc-1234567890-abcdef123456789012345678901234567890".into(),
"".into(),
);
let tokens = BrowserTokens::new(crate::test_fixtures::BROWSER_LONG.into(), "".into());

let result = tokens.validate();
assert!(result.is_err());
Expand All @@ -224,8 +221,8 @@ mod tests {
#[test]
fn test_browser_tokens_xoxd_with_newlines() {
let tokens = BrowserTokens::new(
"xoxc-1234567890-abcdef123456789012345678901234567890".into(),
"xoxd-abc\ndef".into(),
crate::test_fixtures::BROWSER_LONG.into(),
crate::test_fixtures::BROWSER_COOKIE_NEWLINE.into(),
);

let result = tokens.validate();
Expand All @@ -235,8 +232,8 @@ mod tests {
#[test]
fn test_browser_tokens_xoxd_carriage_return() {
let tokens = BrowserTokens::new(
"xoxc-1234567890-abcdef123456789012345678901234567890".into(),
"xoxd-abc\rdef".into(),
crate::test_fixtures::BROWSER_LONG.into(),
crate::test_fixtures::BROWSER_COOKIE_CARRIAGE_RETURN.into(),
);

let result = tokens.validate();
Expand All @@ -248,8 +245,8 @@ mod tests {
// Older xoxd cookies might not start with xoxd-
// but should be long encoded values
let tokens = BrowserTokens::new(
"xoxc-1234567890-abcdef123456789012345678901234567890".into(),
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c".into(),
crate::test_fixtures::BROWSER_LONG.into(),
crate::test_fixtures::LEGACY_BROWSER_COOKIE.into(),
);

// Long JWT-like cookie should be accepted
Expand All @@ -260,7 +257,7 @@ mod tests {
fn test_browser_tokens_short_non_xoxd() {
// Short non-xoxd cookie is likely wrong
let tokens = BrowserTokens::new(
"xoxc-1234567890-abcdef123456789012345678901234567890".into(),
crate::test_fixtures::BROWSER_LONG.into(),
"shortcookie".into(),
);

Expand All @@ -271,8 +268,8 @@ mod tests {
#[test]
fn test_is_valid_format() {
let valid = BrowserTokens::new(
"xoxc-1234567890-abcdef123456789012345678901234567890".into(),
"xoxd-abcdefghijklmnopqrstuvwxyz1234567890".into(),
crate::test_fixtures::BROWSER_LONG.into(),
crate::test_fixtures::BROWSER_COOKIE.into(),
);
assert!(valid.is_valid_format());

Expand Down
Loading
Loading