64 lines
1.6 KiB
Go
64 lines
1.6 KiB
Go
|
|
package cmd
|
||
|
|
|
||
|
|
import (
|
||
|
|
"fmt"
|
||
|
|
"net/http"
|
||
|
|
"net/url"
|
||
|
|
"os"
|
||
|
|
"strings"
|
||
|
|
|
||
|
|
"github.com/spf13/cobra"
|
||
|
|
|
||
|
|
"guardianproject.dev/ops/nix-cache-login/internal/config"
|
||
|
|
"guardianproject.dev/ops/nix-cache-login/internal/netrc"
|
||
|
|
)
|
||
|
|
|
||
|
|
var logoutCmd = &cobra.Command{
|
||
|
|
Use: "logout",
|
||
|
|
Short: "Remove tokens and revoke session",
|
||
|
|
Long: `Removes the access token from the netrc file, deletes the stored
|
||
|
|
refresh token, and revokes the refresh token at Keycloak.`,
|
||
|
|
RunE: runLogout,
|
||
|
|
}
|
||
|
|
|
||
|
|
func init() {
|
||
|
|
rootCmd.AddCommand(logoutCmd)
|
||
|
|
}
|
||
|
|
|
||
|
|
func runLogout(cmd *cobra.Command, args []string) error {
|
||
|
|
// Read and revoke refresh token if it exists
|
||
|
|
rtPath := config.RefreshTokenPath()
|
||
|
|
if rtData, err := os.ReadFile(rtPath); err == nil && len(rtData) > 0 {
|
||
|
|
refreshToken := string(rtData)
|
||
|
|
|
||
|
|
// Revoke at Keycloak
|
||
|
|
revokeURL := strings.TrimSuffix(cfg.Issuer, "/") + "/protocol/openid-connect/revoke"
|
||
|
|
data := url.Values{
|
||
|
|
"token": {refreshToken},
|
||
|
|
"token_type_hint": {"refresh_token"},
|
||
|
|
"client_id": {cfg.ClientID},
|
||
|
|
}
|
||
|
|
|
||
|
|
resp, err := http.PostForm(revokeURL, data)
|
||
|
|
if err != nil {
|
||
|
|
fmt.Fprintf(os.Stderr, "Warning: could not revoke token at Keycloak: %v\n", err)
|
||
|
|
} else {
|
||
|
|
resp.Body.Close()
|
||
|
|
if resp.StatusCode >= 400 {
|
||
|
|
fmt.Fprintf(os.Stderr, "Warning: token revocation returned status %d\n", resp.StatusCode)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Delete refresh token file
|
||
|
|
os.Remove(rtPath)
|
||
|
|
}
|
||
|
|
|
||
|
|
// Remove token from netrc
|
||
|
|
if err := netrc.Remove(cfg.NetrcPath, cfg.CacheHost); err != nil {
|
||
|
|
return fmt.Errorf("removing netrc entry: %w", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
fmt.Fprintln(os.Stderr, "Logged out.")
|
||
|
|
return nil
|
||
|
|
}
|