62 lines
1.6 KiB
Go
62 lines
1.6 KiB
Go
package keycloak
|
|
|
|
import (
|
|
"antrian-operasi/internal/config"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
)
|
|
|
|
type IKeycloakService interface {
|
|
FetchTokenUsingRefreshToken(c context.Context, refreshToken string) (*TokenResponse, error)
|
|
}
|
|
|
|
type KeycloakService struct {
|
|
config config.KeycloakConfig
|
|
}
|
|
|
|
func NewKeycloakService(cfg config.KeycloakConfig) IKeycloakService {
|
|
return KeycloakService{cfg}
|
|
}
|
|
|
|
func (s KeycloakService) FetchTokenUsingRefreshToken(c context.Context, refreshToken string) (*TokenResponse, error) {
|
|
refreshTokenUrl := s.config.BaseUrl + "/realms/" + s.config.Realm + "/protocol/openid-connect/token"
|
|
bodyRequest := url.Values{}
|
|
bodyRequest.Set("grant_type", "refresh_token")
|
|
bodyRequest.Set("client_id", s.config.Audience)
|
|
bodyRequest.Set("client_secret", s.config.SecretKey)
|
|
bodyRequest.Set("refresh_token", refreshToken)
|
|
|
|
client := &http.Client{}
|
|
req, err := http.NewRequestWithContext(c, http.MethodPost, refreshTokenUrl, strings.NewReader(bodyRequest.Encode()))
|
|
if err != nil {
|
|
log.Printf("error request token %s", err)
|
|
}
|
|
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
|
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
log.Printf("error response %s", err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
var errResp TokenErrorResponse
|
|
json.NewDecoder(resp.Body).Decode(&errResp)
|
|
|
|
return nil, fmt.Errorf("Keycloak error : %s - %s", errResp.Error, errResp.ErrorDescription)
|
|
}
|
|
|
|
var tokenResp TokenResponse
|
|
err = json.NewDecoder(resp.Body).Decode(&tokenResp)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &tokenResp, nil
|
|
}
|