84 lines
2.6 KiB
Go
84 lines
2.6 KiB
Go
package auth
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"time"
|
|
|
|
"service/internal/infrastructure/cache"
|
|
"service/internal/interfaces/satusehat"
|
|
"service/pkg/errors"
|
|
"service/pkg/logger"
|
|
)
|
|
|
|
// Service mendefinisikan interface untuk manajemen Auth Satu Sehat di level aplikasi.
|
|
type Service interface {
|
|
GetToken(ctx context.Context) (map[string]interface{}, error)
|
|
RefreshToken(ctx context.Context) (map[string]interface{}, error)
|
|
}
|
|
|
|
type service struct {
|
|
client satusehat.SatuSehatClient
|
|
cache *cache.Manager
|
|
}
|
|
|
|
// NewService membuat instance baru dari auth service.
|
|
func NewService(client satusehat.SatuSehatClient, cacheManager *cache.Manager) Service {
|
|
return &service{
|
|
client: client,
|
|
cache: cacheManager,
|
|
}
|
|
}
|
|
|
|
func (s *service) GetToken(ctx context.Context) (map[string]interface{}, error) {
|
|
cacheKey := "satusehat:auth_data"
|
|
|
|
// 1. Coba ambil dari Redis cache (sangat efisien untuk multi-instance/load balancer)
|
|
if s.cache != nil {
|
|
var cachedToken string
|
|
if err := s.cache.Get(ctx, cacheKey, &cachedToken); err == nil && cachedToken != "" {
|
|
var data map[string]interface{}
|
|
if err := json.Unmarshal([]byte(cachedToken), &data); err == nil {
|
|
logger.Default().Debug("🔑 Mendapatkan token Satu Sehat dari Redis Cache")
|
|
return data, nil
|
|
}
|
|
}
|
|
}
|
|
|
|
// 2. Jika tidak ada di Redis (atau expired), ambil dari Klien Kemenkes
|
|
data, err := s.client.GetAccessToken(ctx)
|
|
if err != nil {
|
|
logger.Default().Error("Gagal mendapatkan token dari SatuSehat Client", logger.ErrorField(err))
|
|
return nil, errors.InternalError().Message("Gagal mendapatkan token Satu Sehat dari Kemenkes").Cause(err).Build()
|
|
}
|
|
|
|
// 3. Simpan ke Redis cache (Diset 55 menit karena token Kemenkes biasanya expired dalam 60 menit)
|
|
if s.cache != nil {
|
|
if bytes, err := json.Marshal(data); err == nil {
|
|
_ = s.cache.Set(ctx, cacheKey, string(bytes), 55*time.Minute)
|
|
}
|
|
}
|
|
|
|
return data, nil
|
|
}
|
|
|
|
func (s *service) RefreshToken(ctx context.Context) (map[string]interface{}, error) {
|
|
// Refresh token secara paksa melewati cache in-memory HTTP Client
|
|
data, err := s.client.RefreshToken(ctx)
|
|
if err != nil {
|
|
logger.Default().Error("Gagal me-refresh token SatuSehat Client", logger.ErrorField(err))
|
|
return nil, errors.InternalError().Message("Gagal melakukan refresh token Satu Sehat").Cause(err).Build()
|
|
}
|
|
|
|
// Update sinkronisasi token terbaru ke Redis cache
|
|
if s.cache != nil {
|
|
cacheKey := "satusehat:auth_data"
|
|
if bytes, err := json.Marshal(data); err == nil {
|
|
_ = s.cache.Set(ctx, cacheKey, string(bytes), 55*time.Minute)
|
|
}
|
|
}
|
|
|
|
logger.Default().Info("🔄 Token Satu Sehat berhasil di-refresh secara manual")
|
|
return data, nil
|
|
}
|