77 lines
2.2 KiB
Go
77 lines
2.2 KiB
Go
package http
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"primaya-api/cpone-middleware/internal/databaseconfig"
|
|
"primaya-api/cpone-middleware/internal/repository"
|
|
)
|
|
|
|
type selectedRepositoryKey struct{}
|
|
|
|
type DatabaseResolver interface {
|
|
Resolve(ctx context.Context, code string) (repository.MySQLLayananRepository, error)
|
|
}
|
|
|
|
func BearerAuth(staticToken string, next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if bearerToken(r.Header.Get("Authorization")) != staticToken {
|
|
WriteJSON(w, http.StatusUnauthorized, Response{
|
|
Success: false,
|
|
Message: "Unauthenticated.",
|
|
Data: nil,
|
|
})
|
|
return
|
|
}
|
|
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
|
|
func SelectDatabase(resolver DatabaseResolver, next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
code := strings.TrimSpace(r.Header.Get("X-RS-Code"))
|
|
if code == "" {
|
|
code = strings.TrimSpace(r.URL.Query().Get("kode_rs"))
|
|
}
|
|
if code == "" {
|
|
WriteJSON(w, http.StatusUnprocessableEntity, Response{Success: false,
|
|
Message: "Kode RS wajib diisi melalui header X-RS-Code atau parameter kode_rs", Data: nil})
|
|
return
|
|
}
|
|
code = databaseconfig.NormalizeRSCode(code)
|
|
|
|
repo, err := resolver.Resolve(r.Context(), code)
|
|
if err != nil {
|
|
if errors.Is(err, databaseconfig.ErrRSCodeMismatch) {
|
|
WriteJSON(w, http.StatusForbidden, Response{Success: false,
|
|
Message: "X-RS-Code tidak sesuai dengan instance CPONE", Data: nil})
|
|
return
|
|
}
|
|
WriteJSON(w, http.StatusServiceUnavailable, Response{Success: false,
|
|
Message: "Database HIS tidak dapat diakses", Data: nil})
|
|
return
|
|
}
|
|
w.Header().Set("X-RS-Code", code)
|
|
ctx := context.WithValue(r.Context(), selectedRepositoryKey{}, repo)
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
})
|
|
}
|
|
|
|
func selectedRepository(ctx context.Context) (repository.MySQLLayananRepository, bool) {
|
|
repo, ok := ctx.Value(selectedRepositoryKey{}).(repository.MySQLLayananRepository)
|
|
return repo, ok
|
|
}
|
|
|
|
func bearerToken(header string) string {
|
|
const prefix = "Bearer "
|
|
if !strings.HasPrefix(header, prefix) {
|
|
return ""
|
|
}
|
|
|
|
return strings.TrimSpace(strings.TrimPrefix(header, prefix))
|
|
}
|