Files
egutierrez 47fac22230 chore: auto-commit (799 archivos)
- .claude/CLAUDE.md
- .claude/commands/subagentes.md
- .claude/rules/INDEX.md
- .mcp.json
- bash/functions/cybersecurity/analyze_dns.md
- bash/functions/cybersecurity/audit_http_headers.md
- bash/functions/cybersecurity/audit_ssh_config.md
- bash/functions/cybersecurity/check_firewall.md
- bash/functions/cybersecurity/detect_suspicious_users.md
- bash/functions/cybersecurity/encrypt_file.md
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 00:28:20 +02:00

47 lines
2.1 KiB
Markdown

---
name: oauth2_exchange
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func Oauth2Exchange(config OAuthConfig, code string) (OAuthTokens, error)"
description: "Intercambia un authorization code por tokens OAuth2. POST al TokenURL del proveedor con grant_type=authorization_code y las credenciales del cliente. Retorna OAuthTokens con AccessToken, RefreshToken y ExpiresAt calculado."
tags: [oauth, oauth2, auth, token, exchange, http, infra, pendiente-usar]
uses_functions: []
uses_types: [OAuthConfig_go_infra, OAuthTokens_go_infra]
returns: [OAuthTokens_go_infra]
returns_optional: false
error_type: error_go_core
imports: [encoding/json, fmt, io, net/http, net/url, strings, time]
params:
- name: config
desc: "OAuthConfig del proveedor con ClientID, ClientSecret, TokenURL y RedirectURL"
- name: code
desc: "authorization code recibido en el callback tras redirigir al usuario a la URL de Oauth2AuthURL"
output: "OAuthTokens con access/refresh tokens. ExpiresAt = now + expires_in del proveedor"
tested: true
tests: ["intercambia code por tokens contra mock server", "rechaza code vacio", "propaga error si proveedor devuelve error"]
test_file_path: "functions/infra/oauth2_exchange_test.go"
file_path: "functions/infra/oauth2_exchange.go"
---
## Ejemplo
```go
code := r.URL.Query().Get("code")
state := r.URL.Query().Get("state")
// Validar state contra el guardado en cookie/session...
tokens, err := Oauth2Exchange(googleConfig, code)
if err != nil {
HTTPErrorResponse(w, HTTPError{Status: 500, Code: "oauth_error", Message: err.Error()})
return
}
// Usar tokens.AccessToken para llamar a APIs del proveedor
```
## Notas
Impura — hace POST HTTP al TokenURL con timeout de 30s, y usa `time.Now()` para calcular ExpiresAt. El body es application/x-www-form-urlencoded (estandar OAuth2). Si el proveedor retorna JSON con campo `error` se wrappea en un error descriptivo. El ClientSecret se envia en el body (no en header Authorization Basic) para compatibilidad amplia — la mayoria de proveedores aceptan ambos. NO valida el state anti-CSRF: eso debe hacerlo el handler del callback antes de llamar a Oauth2Exchange.