mirror of
https://github.com/MODSetter/SurfSense
synced 2026-06-21 13:44:09 +00:00
feat: add Atlassian OAuth support for Jira and Confluence
- Introduced a shared schema for Atlassian OAuth 2.0 credentials, accommodating both Jira and Confluence. - Updated Jira connector routes to utilize the new AtlassianAuthCredentialsBase for handling OAuth tokens. - Enhanced configuration to include new environment variables for Jira OAuth integration. - Refactored token handling in Jira indexing logic to support the new shared credential structure.
This commit is contained in:
@@ -95,6 +95,11 @@ class Config:
|
||||
NOTION_CLIENT_SECRET = os.getenv("NOTION_CLIENT_SECRET")
|
||||
NOTION_REDIRECT_URI = os.getenv("NOTION_REDIRECT_URI")
|
||||
|
||||
# Jira OAuth
|
||||
JIRA_CLIENT_ID = os.getenv("JIRA_CLIENT_ID")
|
||||
JIRA_CLIENT_SECRET = os.getenv("JIRA_CLIENT_SECRET")
|
||||
JIRA_REDIRECT_URI = os.getenv("JIRA_REDIRECT_URI")
|
||||
|
||||
# Linear OAuth
|
||||
LINEAR_CLIENT_ID = os.getenv("LINEAR_CLIENT_ID")
|
||||
LINEAR_CLIENT_SECRET = os.getenv("LINEAR_CLIENT_SECRET")
|
||||
|
||||
@@ -24,7 +24,7 @@ from app.db import (
|
||||
User,
|
||||
get_async_session,
|
||||
)
|
||||
from app.schemas.jira_auth_credentials import JiraAuthCredentialsBase
|
||||
from app.schemas.atlassian_auth_credentials import AtlassianAuthCredentialsBase
|
||||
from app.users import current_active_user
|
||||
from app.utils.oauth_security import OAuthStateManager, TokenEncryption
|
||||
|
||||
@@ -392,7 +392,7 @@ async def refresh_jira_token(
|
||||
try:
|
||||
logger.info(f"Refreshing Jira token for connector {connector.id}")
|
||||
|
||||
credentials = JiraAuthCredentialsBase.from_dict(connector.config)
|
||||
credentials = AtlassianAuthCredentialsBase.from_dict(connector.config)
|
||||
|
||||
# Decrypt tokens if they are encrypted
|
||||
token_encryption = get_token_encryption()
|
||||
|
||||
+17
-2
@@ -1,9 +1,23 @@
|
||||
"""
|
||||
Atlassian OAuth 2.0 Authentication Credentials Schema.
|
||||
|
||||
Shared schema for both Jira and Confluence OAuth credentials.
|
||||
Both products use the same Atlassian OAuth 2.0 (3LO) flow and token structure.
|
||||
"""
|
||||
|
||||
from datetime import UTC, datetime
|
||||
|
||||
from pydantic import BaseModel, field_validator
|
||||
|
||||
|
||||
class JiraAuthCredentialsBase(BaseModel):
|
||||
class AtlassianAuthCredentialsBase(BaseModel):
|
||||
"""
|
||||
Base model for Atlassian OAuth 2.0 credentials.
|
||||
|
||||
Used for both Jira and Confluence connectors since they share
|
||||
the same Atlassian OAuth infrastructure and token structure.
|
||||
"""
|
||||
|
||||
access_token: str
|
||||
refresh_token: str | None = None
|
||||
token_type: str = "Bearer"
|
||||
@@ -39,7 +53,7 @@ class JiraAuthCredentialsBase(BaseModel):
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: dict) -> "JiraAuthCredentialsBase":
|
||||
def from_dict(cls, data: dict) -> "AtlassianAuthCredentialsBase":
|
||||
"""Create credentials from dictionary."""
|
||||
expires_at = None
|
||||
if data.get("expires_at"):
|
||||
@@ -70,3 +84,4 @@ class JiraAuthCredentialsBase(BaseModel):
|
||||
if isinstance(v, datetime):
|
||||
return v if v.tzinfo else v.replace(tzinfo=UTC)
|
||||
return v
|
||||
|
||||
@@ -131,8 +131,8 @@ async def index_jira_issues(
|
||||
return 0, f"Failed to decrypt Jira tokens: {e!s}"
|
||||
|
||||
try:
|
||||
from app.schemas.jira_auth_credentials import JiraAuthCredentialsBase
|
||||
credentials = JiraAuthCredentialsBase.from_dict(config_data)
|
||||
from app.schemas.atlassian_auth_credentials import AtlassianAuthCredentialsBase
|
||||
credentials = AtlassianAuthCredentialsBase.from_dict(config_data)
|
||||
except Exception as e:
|
||||
await task_logger.log_task_failure(
|
||||
log_entry,
|
||||
@@ -160,7 +160,7 @@ async def index_jira_issues(
|
||||
config_data["access_token"] = token_encryption.decrypt_token(
|
||||
config_data["access_token"]
|
||||
)
|
||||
credentials = JiraAuthCredentialsBase.from_dict(config_data)
|
||||
credentials = AtlassianAuthCredentialsBase.from_dict(config_data)
|
||||
except Exception as e:
|
||||
await task_logger.log_task_failure(
|
||||
log_entry,
|
||||
|
||||
Reference in New Issue
Block a user