MCPcopy Create free account
hub / github.com/su-kaka/gcli2api / ServiceAccount

Class ServiceAccount

src/google_oauth_api.py:249–328  ·  view source on GitHub ↗

Service Account类

Source from the content-addressed store, hash-verified

247
248
249class ServiceAccount:
250 """Service Account类"""
251
252 def __init__(
253 self, email: str, private_key: str, project_id: str = None, scopes: List[str] = None
254 ):
255 self.email = email
256 self.private_key = private_key
257 self.project_id = project_id
258 self.scopes = scopes or []
259
260 # 反代配置将在使用时异步获取
261 self.oauth_base_url = None
262 self.token_endpoint = None
263
264 self.access_token: Optional[str] = None
265 self.expires_at: Optional[datetime] = None
266
267 def is_expired(self) -> bool:
268 """检查token是否过期"""
269 if not self.expires_at:
270 return True
271
272 buffer = timedelta(minutes=3)
273 return (self.expires_at - buffer) <= datetime.now(timezone.utc)
274
275 def create_jwt(self) -> str:
276 """创建JWT令牌"""
277 now = int(time.time())
278
279 payload = {
280 "iss": self.email,
281 "scope": " ".join(self.scopes) if self.scopes else "",
282 "aud": self.token_endpoint,
283 "exp": now + 3600,
284 "iat": now,
285 }
286
287 return jwt.encode(payload, self.private_key, algorithm="RS256")
288
289 async def get_access_token(self) -> str:
290 """获取访问令牌"""
291 if not self.is_expired() and self.access_token:
292 return self.access_token
293
294 assertion = self.create_jwt()
295
296 data = {"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer", "assertion": assertion}
297
298 try:
299 oauth_base_url = await get_oauth_proxy_url()
300 token_url = f"{oauth_base_url.rstrip('/')}/token"
301 response = await post_async(
302 token_url, data=data, headers={"Content-Type": "application/x-www-form-urlencoded"}
303 )
304 response.raise_for_status()
305
306 token_data = response.json()

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected