-
Notifications
You must be signed in to change notification settings - Fork 111
/
authentication.go
99 lines (79 loc) · 2.41 KB
/
authentication.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package salesforce
import (
"errors"
"fmt"
"net/url"
"os"
force "github.com/ForceCLI/force/lib"
)
const defaultEndpoint = "https://login.salesforce.com"
type authenticationOptions struct {
Endpoint string
Username string
Password string
JWT string
ConnectedApp string
}
func authenticate(options authenticationOptions) (*force.Force, error) {
if options.ConnectedApp == "" {
return nil, fmt.Errorf("connected app client id is required")
}
force.ClientId = options.ConnectedApp
if options.Username == "" {
return nil, fmt.Errorf("username missing")
}
isJWTSelected := options.JWT != ""
isSOAPSelected := options.Password != ""
endpoint, err := endpoint(options)
if err != nil {
return nil, err
}
switch {
case isJWTSelected:
return jwtLogin(endpoint, options)
case isSOAPSelected:
return soapLoginAtEndpoint(endpoint, options.Username, options.Password)
}
return nil, fmt.Errorf("unable to authenticate")
}
func endpoint(options authenticationOptions) (endpoint string, err error) {
isEndpointSelected := options.Endpoint != ""
if !isEndpointSelected {
return defaultEndpoint, nil
}
// URL needs to have scheme lest the force cli lib chokes
uri, err := url.Parse(options.Endpoint)
if err != nil {
return defaultEndpoint, errors.New("unable to parse endpoint: " + options.Endpoint)
}
if uri.Scheme == "" {
uri.Scheme = "https"
}
return uri.String(), nil
}
func jwtLogin(endpoint string, options authenticationOptions) (*force.Force, error) {
tempfile, err := os.CreateTemp("", "")
if err != nil {
return nil, fmt.Errorf("creating tempfile to write rsa key failed: %w", err)
}
defer os.Remove(tempfile.Name())
if _, err = tempfile.WriteString(options.JWT); err != nil {
return nil, fmt.Errorf("writing rsa key to tempfile failed: %w", err)
}
assertion, err := force.JwtAssertionForEndpoint(endpoint, options.Username, tempfile.Name(), options.ConnectedApp)
if err != nil {
return nil, err
}
session, err := force.JWTLoginAtEndpoint(endpoint, assertion)
if err != nil {
return nil, fmt.Errorf("JWT authentication failed: %w", err)
}
return force.NewForce(&session), nil
}
func soapLoginAtEndpoint(endpoint, username, password string) (*force.Force, error) {
session, err := force.ForceSoapLoginAtEndpoint(endpoint, username, password)
if err != nil {
return nil, fmt.Errorf("SOAP authentication failed: %w", err)
}
return force.NewForce(&session), nil
}