Coverage for src/mcp_atlassian/jira/config.py: 98%

41 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-03-10 03:26 +0900

1"""Configuration module for Jira API interactions.""" 

2 

3import os 

4from dataclasses import dataclass 

5from typing import Optional, Literal 

6 

7 

8@dataclass 

9class JiraConfig: 

10 """Jira API configuration. 

11  

12 Handles authentication for both Jira Cloud (using username/API token) 

13 and Jira Server/Data Center (using personal access token). 

14 """ 

15 

16 url: str # Base URL for Jira 

17 auth_type: Literal["basic", "token"] # Authentication type 

18 username: Optional[str] = None # Email or username (Cloud) 

19 api_token: Optional[str] = None # API token (Cloud) 

20 personal_token: Optional[str] = None # Personal access token (Server/DC) 

21 ssl_verify: bool = True # Whether to verify SSL certificates 

22 

23 @property 

24 def is_cloud(self) -> bool: 

25 """Check if this is a cloud instance. 

26  

27 Returns: 

28 True if this is a cloud instance (atlassian.net), False otherwise. 

29 """ 

30 return "atlassian.net" in self.url 

31 

32 @property 

33 def verify_ssl(self) -> bool: 

34 """Compatibility property for old code. 

35  

36 Returns: 

37 The ssl_verify value 

38 """ 

39 return self.ssl_verify 

40 

41 @classmethod 

42 def from_env(cls) -> "JiraConfig": 

43 """Create configuration from environment variables. 

44  

45 Returns: 

46 JiraConfig with values from environment variables 

47  

48 Raises: 

49 ValueError: If required environment variables are missing or invalid 

50 """ 

51 url = os.getenv("JIRA_URL") 

52 if not url: 

53 error_msg = "Missing required JIRA_URL environment variable" 

54 raise ValueError(error_msg) 

55 

56 # Determine authentication type based on available environment variables 

57 username = os.getenv("JIRA_USERNAME") 

58 api_token = os.getenv("JIRA_API_TOKEN") 

59 personal_token = os.getenv("JIRA_PERSONAL_TOKEN") 

60 

61 is_cloud = "atlassian.net" in url 

62 

63 if is_cloud: 

64 if username and api_token: 

65 auth_type = "basic" 

66 else: 

67 error_msg = "Cloud authentication requires JIRA_USERNAME and JIRA_API_TOKEN" 

68 raise ValueError(error_msg) 

69 else: # Server/Data Center 

70 if personal_token: 

71 auth_type = "token" 

72 elif username and api_token: 

73 # Allow basic auth for Server/DC too 

74 auth_type = "basic" 

75 else: 

76 error_msg = "Server/Data Center authentication requires JIRA_PERSONAL_TOKEN" 

77 raise ValueError(error_msg) 

78 

79 # SSL verification (for Server/DC) 

80 ssl_verify_env = os.getenv("JIRA_SSL_VERIFY", "true").lower() 

81 ssl_verify = ssl_verify_env not in ("false", "0", "no") 

82 

83 return cls( 

84 url=url, 

85 auth_type=auth_type, 

86 username=username, 

87 api_token=api_token, 

88 personal_token=personal_token, 

89 ssl_verify=ssl_verify 

90 )