workspace-mcp 1.1.7__py3-none-any.whl → 1.1.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- auth/google_auth.py +1 -1
- auth/oauth21/__init__.py +108 -0
- auth/oauth21/compat.py +422 -0
- auth/oauth21/config.py +380 -0
- auth/oauth21/discovery.py +232 -0
- auth/oauth21/example_config.py +303 -0
- auth/oauth21/handler.py +440 -0
- auth/oauth21/http.py +270 -0
- auth/oauth21/jwt.py +438 -0
- auth/oauth21/middleware.py +426 -0
- auth/oauth21/oauth2.py +353 -0
- auth/oauth21/sessions.py +519 -0
- auth/oauth21/tokens.py +392 -0
- auth/oauth_callback_server.py +1 -1
- auth/service_decorator.py +2 -5
- core/comments.py +0 -3
- core/server.py +35 -36
- core/utils.py +3 -4
- gcalendar/calendar_tools.py +4 -5
- gchat/chat_tools.py +0 -1
- gdocs/docs_tools.py +73 -16
- gdrive/drive_tools.py +1 -3
- gforms/forms_tools.py +0 -1
- gmail/gmail_tools.py +184 -70
- gsheets/sheets_tools.py +0 -2
- gslides/slides_tools.py +1 -3
- gtasks/tasks_tools.py +1 -2
- main.py +2 -2
- {workspace_mcp-1.1.7.dist-info → workspace_mcp-1.1.9.dist-info}/METADATA +3 -2
- workspace_mcp-1.1.9.dist-info/RECORD +48 -0
- workspace_mcp-1.1.7.dist-info/RECORD +0 -36
- {workspace_mcp-1.1.7.dist-info → workspace_mcp-1.1.9.dist-info}/WHEEL +0 -0
- {workspace_mcp-1.1.7.dist-info → workspace_mcp-1.1.9.dist-info}/entry_points.txt +0 -0
- {workspace_mcp-1.1.7.dist-info → workspace_mcp-1.1.9.dist-info}/licenses/LICENSE +0 -0
- {workspace_mcp-1.1.7.dist-info → workspace_mcp-1.1.9.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,303 @@
|
|
1
|
+
"""
|
2
|
+
OAuth 2.1 Configuration Examples
|
3
|
+
|
4
|
+
Example configurations and usage patterns for OAuth 2.1 authentication.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from typing import Dict, List
|
8
|
+
from .config import OAuth2Config, AuthConfig
|
9
|
+
|
10
|
+
|
11
|
+
def create_google_workspace_oauth2_config() -> OAuth2Config:
|
12
|
+
"""
|
13
|
+
Create OAuth 2.1 configuration optimized for Google Workspace.
|
14
|
+
|
15
|
+
Returns:
|
16
|
+
OAuth 2.1 configuration for Google Workspace
|
17
|
+
"""
|
18
|
+
return OAuth2Config(
|
19
|
+
# Google OAuth 2.0 endpoints
|
20
|
+
authorization_server_url="https://accounts.google.com",
|
21
|
+
|
22
|
+
# Client credentials (set via environment variables)
|
23
|
+
# OAUTH2_CLIENT_ID and OAUTH2_CLIENT_SECRET
|
24
|
+
|
25
|
+
# Token configuration
|
26
|
+
supported_token_types=["jwt"], # Google uses JWTs
|
27
|
+
token_validation_method="local", # Validate JWTs locally
|
28
|
+
expected_audience=None, # Will be set to client_id automatically
|
29
|
+
|
30
|
+
# Session management
|
31
|
+
session_timeout=7200, # 2 hours
|
32
|
+
max_sessions_per_user=5,
|
33
|
+
enable_session_persistence=True,
|
34
|
+
|
35
|
+
# Security settings
|
36
|
+
enable_pkce=True,
|
37
|
+
enable_bearer_passthrough=True,
|
38
|
+
required_scopes=[
|
39
|
+
"https://www.googleapis.com/auth/userinfo.email",
|
40
|
+
"https://www.googleapis.com/auth/userinfo.profile",
|
41
|
+
],
|
42
|
+
|
43
|
+
# Google Workspace resource
|
44
|
+
resource_url="https://www.googleapis.com",
|
45
|
+
|
46
|
+
# Development settings
|
47
|
+
enable_debug_logging=False,
|
48
|
+
allow_insecure_transport=False, # Set to True for localhost development
|
49
|
+
)
|
50
|
+
|
51
|
+
|
52
|
+
def create_development_config() -> AuthConfig:
|
53
|
+
"""
|
54
|
+
Create configuration for development environment.
|
55
|
+
|
56
|
+
Returns:
|
57
|
+
Development authentication configuration
|
58
|
+
"""
|
59
|
+
oauth2_config = OAuth2Config(
|
60
|
+
authorization_server_url="https://accounts.google.com",
|
61
|
+
supported_token_types=["jwt", "opaque"],
|
62
|
+
token_validation_method="introspection", # More flexible for development
|
63
|
+
session_timeout=3600, # 1 hour
|
64
|
+
max_sessions_per_user=10,
|
65
|
+
enable_session_persistence=False, # Don't persist in development
|
66
|
+
enable_pkce=True,
|
67
|
+
enable_bearer_passthrough=True,
|
68
|
+
required_scopes=[
|
69
|
+
"https://www.googleapis.com/auth/userinfo.email",
|
70
|
+
],
|
71
|
+
exempt_paths=[
|
72
|
+
"/health",
|
73
|
+
"/oauth2callback",
|
74
|
+
"/.well-known/",
|
75
|
+
"/docs", # Swagger docs
|
76
|
+
"/redoc", # ReDoc
|
77
|
+
],
|
78
|
+
enable_debug_logging=True,
|
79
|
+
allow_insecure_transport=True, # Allow HTTP for localhost
|
80
|
+
)
|
81
|
+
|
82
|
+
return AuthConfig(
|
83
|
+
oauth2=oauth2_config,
|
84
|
+
enable_legacy_auth=True, # Support legacy for easier migration
|
85
|
+
single_user_mode=False,
|
86
|
+
)
|
87
|
+
|
88
|
+
|
89
|
+
def create_production_config() -> AuthConfig:
|
90
|
+
"""
|
91
|
+
Create configuration for production environment.
|
92
|
+
|
93
|
+
Returns:
|
94
|
+
Production authentication configuration
|
95
|
+
"""
|
96
|
+
oauth2_config = OAuth2Config(
|
97
|
+
authorization_server_url="https://accounts.google.com",
|
98
|
+
supported_token_types=["jwt"],
|
99
|
+
token_validation_method="local",
|
100
|
+
session_timeout=3600, # 1 hour
|
101
|
+
max_sessions_per_user=3, # Limit sessions in production
|
102
|
+
session_cleanup_interval=300, # 5 minutes
|
103
|
+
enable_session_persistence=True,
|
104
|
+
enable_pkce=True,
|
105
|
+
enable_bearer_passthrough=True,
|
106
|
+
required_scopes=[
|
107
|
+
"https://www.googleapis.com/auth/userinfo.email",
|
108
|
+
"https://www.googleapis.com/auth/userinfo.profile",
|
109
|
+
],
|
110
|
+
discovery_cache_ttl=3600, # 1 hour
|
111
|
+
jwks_cache_ttl=3600, # 1 hour
|
112
|
+
exempt_paths=["/health", "/oauth2callback", "/.well-known/"],
|
113
|
+
enable_debug_logging=False,
|
114
|
+
allow_insecure_transport=False,
|
115
|
+
)
|
116
|
+
|
117
|
+
return AuthConfig(
|
118
|
+
oauth2=oauth2_config,
|
119
|
+
enable_legacy_auth=False, # OAuth 2.1 only in production
|
120
|
+
single_user_mode=False,
|
121
|
+
)
|
122
|
+
|
123
|
+
|
124
|
+
def create_single_user_config() -> AuthConfig:
|
125
|
+
"""
|
126
|
+
Create configuration for single-user deployments.
|
127
|
+
|
128
|
+
Returns:
|
129
|
+
Single-user authentication configuration
|
130
|
+
"""
|
131
|
+
# In single-user mode, OAuth 2.1 is optional
|
132
|
+
# Legacy auth will be used primarily
|
133
|
+
return AuthConfig(
|
134
|
+
oauth2=None, # No OAuth 2.1 needed
|
135
|
+
enable_legacy_auth=True,
|
136
|
+
single_user_mode=True,
|
137
|
+
default_user_email=None, # Will be detected from credentials
|
138
|
+
)
|
139
|
+
|
140
|
+
|
141
|
+
def create_hybrid_config() -> AuthConfig:
|
142
|
+
"""
|
143
|
+
Create hybrid configuration supporting both OAuth 2.1 and legacy auth.
|
144
|
+
|
145
|
+
Returns:
|
146
|
+
Hybrid authentication configuration
|
147
|
+
"""
|
148
|
+
oauth2_config = OAuth2Config(
|
149
|
+
authorization_server_url="https://accounts.google.com",
|
150
|
+
supported_token_types=["jwt", "opaque"],
|
151
|
+
token_validation_method="introspection",
|
152
|
+
session_timeout=3600,
|
153
|
+
max_sessions_per_user=5,
|
154
|
+
enable_bearer_passthrough=True,
|
155
|
+
required_scopes=[
|
156
|
+
"https://www.googleapis.com/auth/userinfo.email",
|
157
|
+
],
|
158
|
+
enable_debug_logging=False,
|
159
|
+
)
|
160
|
+
|
161
|
+
return AuthConfig(
|
162
|
+
oauth2=oauth2_config,
|
163
|
+
enable_legacy_auth=True, # Support both methods
|
164
|
+
single_user_mode=False,
|
165
|
+
)
|
166
|
+
|
167
|
+
|
168
|
+
# Example usage patterns
|
169
|
+
async def example_oauth2_server_setup():
|
170
|
+
"""Example of setting up an OAuth 2.1 enabled MCP server."""
|
171
|
+
from ..oauth21.compat import AuthCompatibilityLayer
|
172
|
+
from fastapi import FastAPI
|
173
|
+
|
174
|
+
# Create configuration
|
175
|
+
auth_config = create_google_workspace_oauth2_config()
|
176
|
+
full_config = AuthConfig(oauth2=auth_config)
|
177
|
+
|
178
|
+
# Create compatibility layer
|
179
|
+
auth_layer = AuthCompatibilityLayer(full_config)
|
180
|
+
|
181
|
+
# Create FastAPI app
|
182
|
+
app = FastAPI(title="Google Workspace MCP Server")
|
183
|
+
|
184
|
+
# Add OAuth 2.1 middleware
|
185
|
+
if full_config.is_oauth2_enabled():
|
186
|
+
middleware = auth_layer.create_enhanced_middleware()
|
187
|
+
app.add_middleware(type(middleware), **middleware.__dict__)
|
188
|
+
|
189
|
+
# Start authentication
|
190
|
+
await auth_layer.start()
|
191
|
+
|
192
|
+
return app, auth_layer
|
193
|
+
|
194
|
+
|
195
|
+
def example_environment_variables():
|
196
|
+
"""
|
197
|
+
Example environment variables for OAuth 2.1 configuration.
|
198
|
+
|
199
|
+
Set these in your environment or .env file:
|
200
|
+
"""
|
201
|
+
return {
|
202
|
+
# Required OAuth 2.1 settings
|
203
|
+
"OAUTH2_CLIENT_ID": "your-google-client-id.googleusercontent.com",
|
204
|
+
"OAUTH2_CLIENT_SECRET": "your-google-client-secret",
|
205
|
+
|
206
|
+
# Optional OAuth 2.1 settings
|
207
|
+
"OAUTH2_AUTHORIZATION_SERVER_URL": "https://accounts.google.com",
|
208
|
+
"OAUTH2_EXPECTED_AUDIENCE": "your-client-id",
|
209
|
+
"OAUTH2_SESSION_TIMEOUT": "3600", # 1 hour
|
210
|
+
"OAUTH2_MAX_SESSIONS_PER_USER": "5",
|
211
|
+
"OAUTH2_ENABLE_BEARER_PASSTHROUGH": "true",
|
212
|
+
"OAUTH2_REQUIRED_SCOPES": "https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/userinfo.profile",
|
213
|
+
|
214
|
+
# Development settings
|
215
|
+
"OAUTH2_ENABLE_DEBUG": "false",
|
216
|
+
"OAUTH2_ALLOW_INSECURE_TRANSPORT": "false", # Set to "true" for localhost
|
217
|
+
|
218
|
+
# Legacy compatibility
|
219
|
+
"MCP_SINGLE_USER_MODE": "false",
|
220
|
+
"USER_GOOGLE_EMAIL": "user@example.com", # Default user email
|
221
|
+
"OAUTH2_ENABLE_LEGACY_AUTH": "true",
|
222
|
+
}
|
223
|
+
|
224
|
+
|
225
|
+
def example_client_usage():
|
226
|
+
"""
|
227
|
+
Example of how clients should use OAuth 2.1 authentication.
|
228
|
+
"""
|
229
|
+
return {
|
230
|
+
"bearer_token_usage": {
|
231
|
+
"description": "Send Bearer token in Authorization header",
|
232
|
+
"example": {
|
233
|
+
"headers": {
|
234
|
+
"Authorization": "Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
|
235
|
+
"Mcp-Session-Id": "optional-session-id",
|
236
|
+
"Content-Type": "application/json",
|
237
|
+
}
|
238
|
+
}
|
239
|
+
},
|
240
|
+
|
241
|
+
"authorization_flow": {
|
242
|
+
"description": "OAuth 2.1 authorization code flow with PKCE",
|
243
|
+
"steps": [
|
244
|
+
"1. GET /oauth2/authorize with PKCE parameters",
|
245
|
+
"2. User authorizes in browser",
|
246
|
+
"3. POST /oauth2/token to exchange code for tokens",
|
247
|
+
"4. Use access_token as Bearer token in requests",
|
248
|
+
"5. Use refresh_token to get new access tokens",
|
249
|
+
]
|
250
|
+
},
|
251
|
+
|
252
|
+
"session_management": {
|
253
|
+
"description": "Session-based authentication",
|
254
|
+
"steps": [
|
255
|
+
"1. Perform OAuth flow to get session",
|
256
|
+
"2. Include Mcp-Session-Id header in requests",
|
257
|
+
"3. Optionally include Bearer token for validation",
|
258
|
+
"4. Session maintains user context across requests",
|
259
|
+
]
|
260
|
+
}
|
261
|
+
}
|
262
|
+
|
263
|
+
|
264
|
+
# Configuration validation examples
|
265
|
+
def validate_oauth2_config(config: OAuth2Config) -> List[str]:
|
266
|
+
"""
|
267
|
+
Validate OAuth 2.1 configuration and return any issues.
|
268
|
+
|
269
|
+
Args:
|
270
|
+
config: OAuth 2.1 configuration to validate
|
271
|
+
|
272
|
+
Returns:
|
273
|
+
List of validation issues (empty if valid)
|
274
|
+
"""
|
275
|
+
issues = []
|
276
|
+
|
277
|
+
if not config.client_id:
|
278
|
+
issues.append("client_id is required")
|
279
|
+
|
280
|
+
if not config.authorization_server_url:
|
281
|
+
issues.append("authorization_server_url is required")
|
282
|
+
|
283
|
+
if config.session_timeout <= 0:
|
284
|
+
issues.append("session_timeout must be positive")
|
285
|
+
|
286
|
+
if not config.supported_token_types:
|
287
|
+
issues.append("at least one token type must be supported")
|
288
|
+
|
289
|
+
if config.token_validation_method not in ["local", "introspection"]:
|
290
|
+
issues.append("token_validation_method must be 'local' or 'introspection'")
|
291
|
+
|
292
|
+
return issues
|
293
|
+
|
294
|
+
|
295
|
+
def get_config_recommendations() -> Dict[str, str]:
|
296
|
+
"""Get configuration recommendations for different deployment scenarios."""
|
297
|
+
return {
|
298
|
+
"development": "Use create_development_config() with debug logging enabled",
|
299
|
+
"production": "Use create_production_config() with minimal session limits",
|
300
|
+
"single_user": "Use create_single_user_config() for simple deployments",
|
301
|
+
"migration": "Use create_hybrid_config() to support both OAuth 2.1 and legacy",
|
302
|
+
"google_workspace": "Use create_google_workspace_oauth2_config() for Google-optimized settings",
|
303
|
+
}
|