Passed
Pull Request — master (#885)
by Tolga
02:43
created

internal/engines/balancer/utils.go   A

Size/Duplication

Total Lines 95
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 51
dl 0
loc 95
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A balancer.secureTokenCredentials.RequireTransportSecurity 0 2 1
A balancer.secureTokenCredentials.GetRequestMetadata 0 2 1
A balancer.nonSecureTokenCredentials.GetRequestMetadata 0 2 1
A balancer.nonSecureTokenCredentials.RequireTransportSecurity 0 2 1
A balancer.getOIDCToken 0 28 4
A balancer.setupAuthn 0 17 5
1
package balancer
2
3
import (
4
	"context"
5
	"encoding/json"
6
	"fmt"
7
	"net/http"
8
	"net/url"
9
	"strings"
10
11
	"github.com/Permify/permify/internal/config"
12
)
13
14
// secureTokenCredentials represents a map used for storing secure tokens.
15
// These tokens require transport security.
16
type secureTokenCredentials map[string]string
17
18
// RequireTransportSecurity indicates that transport security is required for these credentials.
19
func (c secureTokenCredentials) RequireTransportSecurity() bool {
20
	return true // Transport security is required for secure tokens.
21
}
22
23
// GetRequestMetadata retrieves the current metadata (secure tokens) for a request.
24
func (c secureTokenCredentials) GetRequestMetadata(context.Context, ...string) (map[string]string, error) {
25
	return c, nil // Returns the secure tokens as metadata with no error.
26
}
27
28
// nonSecureTokenCredentials represents a map used for storing non-secure tokens.
29
// These tokens do not require transport security.
30
type nonSecureTokenCredentials map[string]string
31
32
// RequireTransportSecurity indicates that transport security is not required for these credentials.
33
func (c nonSecureTokenCredentials) RequireTransportSecurity() bool {
34
	return false // Transport security is not required for non-secure tokens.
35
}
36
37
// GetRequestMetadata retrieves the current metadata (non-secure tokens) for a request.
38
func (c nonSecureTokenCredentials) GetRequestMetadata(_ context.Context, _ ...string) (map[string]string, error) {
39
	return c, nil // Returns the non-secure tokens as metadata with no error.
40
}
41
42
// OIDCTokenResponse represents the response from the OIDC token endpoint
43
type OIDCTokenResponse struct {
44
	AccessToken string `json:"access_token"`
45
}
46
47
func getOIDCToken(ctx context.Context, issuer, clientID string) (string, error) {
48
	// Prepare the request data
49
	data := url.Values{}
50
	data.Set("client_id", clientID)
51
	data.Set("grant_type", "client_credentials")
52
53
	// Create the request
54
	req, err := http.NewRequestWithContext(ctx, "POST", issuer+"/token", strings.NewReader(data.Encode()))
55
	if err != nil {
56
		return "", fmt.Errorf("error creating token request: %v", err)
57
	}
58
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
59
60
	// Send the request
61
	client := &http.Client{}
62
	resp, err := client.Do(req)
63
	if err != nil {
64
		return "", fmt.Errorf("error sending token request: %v", err)
65
	}
66
	defer resp.Body.Close()
67
68
	// Decode the response
69
	var tokenResponse OIDCTokenResponse
70
	if err := json.NewDecoder(resp.Body).Decode(&tokenResponse); err != nil {
71
		return "", fmt.Errorf("error decoding token response: %v", err)
72
	}
73
74
	return tokenResponse.AccessToken, nil
75
}
76
77
// setupAuthn configures the authentication token based on the provided authentication method.
78
// It returns the token string and an error if any.
79
func setupAuthn(ctx context.Context, authn *config.Authn) (string, error) {
80
	var token string
81
	var err error
82
83
	switch authn.Method {
84
	case "preshared":
85
		token = authn.Preshared.Keys[0]
86
	case "oidc":
87
		token, err = getOIDCToken(ctx, authn.Oidc.Issuer, authn.Oidc.ClientID)
88
		if err != nil {
89
			return "", fmt.Errorf("failed to get OIDC token: %s", err)
90
		}
91
	default:
92
		return "", fmt.Errorf("unknown authentication method: '%s'", authn.Method)
93
	}
94
95
	return token, nil
96
}
97