Skip to content

Commit 13a37ea

Browse files
committed
refactor: inline oauth.py into app_oauth.py
Removes the separate oauth.py module by inlining its contents directly into app_oauth.py across all three implementations. There was no circular dependency preventing this consolidation.
1 parent 9fb82fe commit 13a37ea

6 files changed

Lines changed: 276 additions & 270 deletions

File tree

claude-agent-sdk/app_oauth.py

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,107 @@
1+
import json
12
import logging
23
import os
4+
from pathlib import Path
35

46
from dotenv import load_dotenv
57
from slack_bolt.async_app import AsyncApp
8+
from slack_bolt.authorization.authorize_result import AuthorizeResult
9+
from slack_bolt.oauth.async_oauth_settings import AsyncOAuthSettings
10+
from slack_sdk.oauth.installation_store import FileInstallationStore
11+
from slack_sdk.oauth.state_store import FileOAuthStateStore
612
from slack_sdk.web.async_client import AsyncWebClient
713

814
from listeners import register_listeners
9-
from oauth import oauth_settings
1015

1116
load_dotenv(dotenv_path=".env", override=False)
1217

1318
logging.basicConfig(level=logging.DEBUG)
19+
logger = logging.getLogger(__name__)
20+
21+
# ---------------------------------------------------------------------------
22+
# OAuth settings
23+
# ---------------------------------------------------------------------------
24+
25+
_manifest = json.loads(Path("manifest.json").read_text())
26+
BOT_SCOPES = _manifest["oauth_config"]["scopes"]["bot"]
27+
USER_SCOPES = _manifest["oauth_config"]["scopes"]["user"]
28+
29+
installation_store = FileInstallationStore(
30+
base_dir="./data/installations",
31+
)
32+
33+
state_store = FileOAuthStateStore(
34+
expiration_seconds=600,
35+
base_dir="./data/states",
36+
)
37+
38+
oauth_settings = AsyncOAuthSettings(
39+
client_id=os.environ.get("SLACK_CLIENT_ID"),
40+
client_secret=os.environ.get("SLACK_CLIENT_SECRET"),
41+
scopes=BOT_SCOPES,
42+
user_scopes=USER_SCOPES,
43+
installation_store=installation_store,
44+
state_store=state_store,
45+
)
46+
47+
# ---------------------------------------------------------------------------
48+
# Bot-token fallback for pre-OAuth first-run experience
49+
# ---------------------------------------------------------------------------
50+
# When installed via Slack CLI, SLACK_BOT_TOKEN is available but Bolt clears
51+
# it when oauth_settings is present. This wrapper lets the bot token serve as
52+
# a fallback so App Home (with the OAuth install URL) and basic bot operations
53+
# work before anyone has completed the OAuth flow.
54+
55+
_fallback_bot_token = os.environ.get("SLACK_BOT_TOKEN")
56+
57+
if _fallback_bot_token:
58+
_original_authorize = oauth_settings.authorize
59+
60+
async def _authorize_with_fallback_bot_token(
61+
*,
62+
context,
63+
enterprise_id,
64+
team_id,
65+
user_id,
66+
actor_enterprise_id=None,
67+
actor_team_id=None,
68+
actor_user_id=None,
69+
):
70+
result = await _original_authorize(
71+
context=context,
72+
enterprise_id=enterprise_id,
73+
team_id=team_id,
74+
user_id=user_id,
75+
actor_enterprise_id=actor_enterprise_id,
76+
actor_team_id=actor_team_id,
77+
actor_user_id=actor_user_id,
78+
)
79+
if result is not None:
80+
return result
81+
82+
logger.info(
83+
"No OAuth installation found (team=%s); falling back to SLACK_BOT_TOKEN",
84+
team_id,
85+
)
86+
try:
87+
fallback_client = AsyncWebClient(
88+
base_url=os.environ.get("SLACK_API_URL", "https://slack.com/api"),
89+
token=_fallback_bot_token,
90+
)
91+
auth_test = await fallback_client.auth_test()
92+
return AuthorizeResult.from_auth_test_response(
93+
auth_test_response=auth_test,
94+
bot_token=_fallback_bot_token,
95+
)
96+
except Exception:
97+
logger.exception("Fallback bot token auth.test failed")
98+
return None
99+
100+
oauth_settings.authorize = _authorize_with_fallback_bot_token
101+
102+
# ---------------------------------------------------------------------------
103+
# App
104+
# ---------------------------------------------------------------------------
14105

15106
app = AsyncApp(
16107
signing_secret=os.environ.get("SLACK_SIGNING_SECRET"),

claude-agent-sdk/oauth.py

Lines changed: 0 additions & 89 deletions
This file was deleted.

openai-agents-sdk/app_oauth.py

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,107 @@
1+
import json
12
import logging
23
import os
4+
from pathlib import Path
35

46
from dotenv import load_dotenv
57
from slack_bolt import App
8+
from slack_bolt.authorization.authorize_result import AuthorizeResult
9+
from slack_bolt.oauth.oauth_settings import OAuthSettings
610
from slack_sdk import WebClient
11+
from slack_sdk.oauth.installation_store import FileInstallationStore
12+
from slack_sdk.oauth.state_store import FileOAuthStateStore
713

814
from listeners import register_listeners
9-
from oauth import oauth_settings
1015

1116
load_dotenv(dotenv_path=".env", override=False)
1217

1318
logging.basicConfig(level=logging.DEBUG)
19+
logger = logging.getLogger(__name__)
20+
21+
# ---------------------------------------------------------------------------
22+
# OAuth settings
23+
# ---------------------------------------------------------------------------
24+
25+
_manifest = json.loads(Path("manifest.json").read_text())
26+
BOT_SCOPES = _manifest["oauth_config"]["scopes"]["bot"]
27+
USER_SCOPES = _manifest["oauth_config"]["scopes"]["user"]
28+
29+
installation_store = FileInstallationStore(
30+
base_dir="./data/installations",
31+
)
32+
33+
state_store = FileOAuthStateStore(
34+
expiration_seconds=600,
35+
base_dir="./data/states",
36+
)
37+
38+
oauth_settings = OAuthSettings(
39+
client_id=os.environ.get("SLACK_CLIENT_ID"),
40+
client_secret=os.environ.get("SLACK_CLIENT_SECRET"),
41+
scopes=BOT_SCOPES,
42+
user_scopes=USER_SCOPES,
43+
installation_store=installation_store,
44+
state_store=state_store,
45+
)
46+
47+
# ---------------------------------------------------------------------------
48+
# Bot-token fallback for pre-OAuth first-run experience
49+
# ---------------------------------------------------------------------------
50+
# When installed via Slack CLI, SLACK_BOT_TOKEN is available but Bolt clears
51+
# it when oauth_settings is present. This wrapper lets the bot token serve as
52+
# a fallback so App Home (with the OAuth install URL) and basic bot operations
53+
# work before anyone has completed the OAuth flow.
54+
55+
_fallback_bot_token = os.environ.get("SLACK_BOT_TOKEN")
56+
57+
if _fallback_bot_token:
58+
_original_authorize = oauth_settings.authorize
59+
60+
def _authorize_with_fallback_bot_token(
61+
*,
62+
context,
63+
enterprise_id,
64+
team_id,
65+
user_id,
66+
actor_enterprise_id=None,
67+
actor_team_id=None,
68+
actor_user_id=None,
69+
):
70+
result = _original_authorize(
71+
context=context,
72+
enterprise_id=enterprise_id,
73+
team_id=team_id,
74+
user_id=user_id,
75+
actor_enterprise_id=actor_enterprise_id,
76+
actor_team_id=actor_team_id,
77+
actor_user_id=actor_user_id,
78+
)
79+
if result is not None:
80+
return result
81+
82+
logger.info(
83+
"No OAuth installation found (team=%s); falling back to SLACK_BOT_TOKEN",
84+
team_id,
85+
)
86+
try:
87+
fallback_client = WebClient(
88+
base_url=os.environ.get("SLACK_API_URL", "https://slack.com/api"),
89+
token=_fallback_bot_token,
90+
)
91+
auth_test = fallback_client.auth_test()
92+
return AuthorizeResult.from_auth_test_response(
93+
auth_test_response=auth_test,
94+
bot_token=_fallback_bot_token,
95+
)
96+
except Exception:
97+
logger.exception("Fallback bot token auth.test failed")
98+
return None
99+
100+
oauth_settings.authorize = _authorize_with_fallback_bot_token
101+
102+
# ---------------------------------------------------------------------------
103+
# App
104+
# ---------------------------------------------------------------------------
14105

15106
app = App(
16107
signing_secret=os.environ.get("SLACK_SIGNING_SECRET"),

openai-agents-sdk/oauth.py

Lines changed: 0 additions & 89 deletions
This file was deleted.

0 commit comments

Comments
 (0)