@@ -3,35 +3,200 @@ package cfclient
3
3
import (
4
4
"errors"
5
5
"fmt"
6
+ "log"
7
+ "net/url"
6
8
)
7
9
8
10
type IDP struct {
9
- Access_token string `json:"access_token,omitempty"`
10
- Accounts []string `json:"accounts,omitempty"`
11
- ApiHost string `json:"apiHost,omitempty"`
12
- ApiPathPrefix string `json:"apiPathPrefix,omitempty"`
13
- ApiURL string `json:"apiURL,omitempty"`
14
- AppId string `json:"appId,omitempty"`
15
- AuthURL string `json:"authURL,omitempty"`
16
- ClientHost string `json:"clientHost,omitempty"`
17
- ClientId string `json:"clientId,omitempty"`
18
- ClientName string `json:"clientName,omitempty"`
19
- ClientSecret string `json:"clientSecret,omitempty"`
20
- ClientType string `json:"clientType,omitempty"`
21
- CookieIv string `json:"cookieIv,omitempty"`
22
- CookieKey string `json:"cookieKey,omitempty"`
23
- DisplayName string `json:"displayName,omitempty"`
24
- ID string `json:"_id,omitempty"`
25
- IDPLoginUrl string `json:"IDPLoginUrl,omitempty"`
26
- LoginUrl string `json:"loginUrl,omitempty"`
27
- RedirectUiUrl string `json:"redirectUiUrl,omitempty"`
28
- RedirectUrl string `json:"redirectUrl,omitempty"`
29
- RefreshTokenURL string `json:"refreshTokenURL,omitempty"`
30
- Scopes []string `json:"scopes,omitempty"`
31
- Tenant string `json:"tenant,omitempty"`
32
- TokenSecret string `json:"tokenSecret,omitempty"`
33
- TokenURL string `json:"tokenURL,omitempty"`
34
- UserProfileURL string `json:"userProfileURL,omitempty"`
11
+ ID string `json:"_id,omitempty"`
12
+ Access_token string `json:"access_token,omitempty"`
13
+ Accounts []string `json:"accounts,omitempty"`
14
+ ClientName string `json:"clientName,omitempty"` // IDP name
15
+ ClientType string `json:"clientType,omitempty"` // IDP type
16
+ DisplayName string `json:"displayName,omitempty"`
17
+ LoginUrl string `json:"loginUrl,omitempty"` // Login url in Codefresh
18
+ RedirectUiUrl string `json:"redirectUiUrl,omitempty"` // Redicrect url Codefresh UI
19
+ RedirectUrl string `json:"redirectUrl,omitempty"`
20
+ ClientId string `json:"clientId,omitempty"` // All providers (base)
21
+ ClientSecret string `json:"clientSecret,omitempty"` // All providers (base)
22
+ ApiHost string `json:"apiHost,omitempty"` // GitHub
23
+ ApiPathPrefix string `json:"apiPathPrefix,omitempty"` // Github
24
+ // Bitbucket, Gitlab
25
+ ApiURL string `json:"apiURL,omitempty"`
26
+ // Azure, Okta, onelogin,saml
27
+ AppId string `json:"appId,omitempty"`
28
+ // Github, Gitlab
29
+ AuthURL string `json:"authURL,omitempty"`
30
+ // saml, okta, onelogin, auth0, azure, google, google-cloud-sr
31
+ ClientHost string `json:"clientHost,omitempty"`
32
+ // Azure
33
+ CookieIv string `json:"cookieIv,omitempty"`
34
+ // Azure
35
+ CookieKey string `json:"cookieKey,omitempty"`
36
+ // Azure
37
+ IDPLoginUrl string `json:"IDPLoginUrl,omitempty"`
38
+ // Bitbucket
39
+ RefreshTokenURL string `json:"refreshTokenURL,omitempty"`
40
+ // Multiple - computed
41
+ Scopes []string `json:"scopes,omitempty"`
42
+ // Azure
43
+ Tenant string `json:"tenant,omitempty"`
44
+ TokenSecret string `json:"tokenSecret,omitempty"`
45
+ // Okta, Bitbucket, GitHub, Keycloak
46
+ TokenURL string `json:"tokenURL,omitempty"`
47
+ // Github, Gitlab
48
+ UserProfileURL string `json:"userProfileURL,omitempty"`
49
+ // Okta
50
+ SyncMirrorAccounts []string `json:"syncMirrorAccounts,omitempty"`
51
+ // Google, Ldap
52
+ AllowedGroupsForSync string `json:"allowedGroupsForSync,omitempty"`
53
+ // Google
54
+ Subject string `json:"subject,omitempty"`
55
+ // Google
56
+ KeyFile string `json:"keyfile,omitempty"`
57
+ // Google
58
+ SyncField string `json:"syncField,omitempty"`
59
+ // Azure
60
+ AutoGroupSync bool `json:"autoGroupSync,omitempty"`
61
+ // Google,Okta,saml
62
+ ActivateUserAfterSync bool `json:"activateUserAfterSync,omitempty"`
63
+ // Azure
64
+ SyncInterval string `json:"syncInterval,omitempty"`
65
+ // Onelogin
66
+ ApiClientId string `json:"apiClientId,omitempty"`
67
+ // Onelogin
68
+ ApiClientSecret string `json:"apiClientSecret,omitempty"`
69
+ // Keycloak
70
+ Host string `json:"host,omitempty"`
71
+ // keycloak
72
+ Realm string `json:"realm,omitempty"`
73
+ // SAML
74
+ EntryPoint string `json:"entryPoint,omitempty"`
75
+ // SAML
76
+ ApplicationCert string `json:"cert,omitempty"`
77
+ // SAML
78
+ SamlProvider string `json:"provider,omitempty"`
79
+ // ldap
80
+ Password string `json:"password,omitempty"`
81
+ Url string `json:"url,omitempty"`
82
+ DistinguishedName string `json:"distinguishedName,omitempty"`
83
+ SearchBase string `json:"searchBase,omitempty"`
84
+ SearchFilter string `json:"searchFilter,omitempty"`
85
+ SearchBaseForSync string `json:"searchBaseForSync,omitempty"`
86
+ Certificate string `json:"certificate,omitempty"`
87
+ }
88
+
89
+ // Return the appropriate API endpoint for platform and account scoped IDPs
90
+ func getAPIEndpoint (isGlobal bool ) string {
91
+ // If IDP is platform scoped
92
+ if isGlobal {
93
+ return "/admin/idp"
94
+ } else {
95
+ return "/idp/account"
96
+ }
97
+ }
98
+
99
+ // Currently on create the API sometimes (like when creating saml idps) returns a different structure for accounts than on read making the client crash on decode
100
+ // For now we are disabling response decode and in the resource will instead call the read function again
101
+ func (client * Client ) CreateIDP (idp * IDP , isGlobal bool ) (id string , err error ) {
102
+
103
+ body , err := EncodeToJSON (idp )
104
+
105
+ if err != nil {
106
+ return "" , err
107
+ }
108
+ opts := RequestOptions {
109
+ Path : getAPIEndpoint (isGlobal ),
110
+ Method : "POST" ,
111
+ Body : body ,
112
+ }
113
+
114
+ resp , err := client .RequestAPI (& opts )
115
+
116
+ if err != nil {
117
+ log .Printf ("[DEBUG] Call to API for IDP creation failed with Error = %v for Body %v" , err , body )
118
+ return "" , err
119
+ }
120
+
121
+ var respIDP map [string ]interface {}
122
+ err = DecodeResponseInto (resp , & respIDP )
123
+
124
+ if err != nil {
125
+ return "" , nil
126
+ }
127
+
128
+ return respIDP ["id" ].(string ), nil
129
+ }
130
+
131
+ // Currently on update the API returns a different structure for accounts than on read making the client crash on decode
132
+ // For now we are disabling response decode and in the resource will instead call the read function again
133
+ func (client * Client ) UpdateIDP (idp * IDP , isGlobal bool ) error {
134
+
135
+ body , err := EncodeToJSON (idp )
136
+
137
+ if err != nil {
138
+ return err
139
+ }
140
+ opts := RequestOptions {
141
+ Path : getAPIEndpoint (isGlobal ),
142
+ Method : "PUT" ,
143
+ Body : body ,
144
+ }
145
+
146
+ _ , err = client .RequestAPI (& opts )
147
+
148
+ if err != nil {
149
+ log .Printf ("[DEBUG] Call to API for IDP update failed with Error = %v for Body %v" , err , body )
150
+ return err
151
+ }
152
+
153
+ // var respIDP IDP
154
+ // err = DecodeResponseInto(resp, &respIDP)
155
+ // if err != nil {
156
+ // return nil, err
157
+ // }
158
+
159
+ return nil
160
+ }
161
+
162
+ func (client * Client ) DeleteIDP (id string ) error {
163
+ baseUrl := getAPIEndpoint (true )
164
+ fullPath := fmt .Sprintf ("%s/%s" , baseUrl , url .PathEscape (id ))
165
+ opts := RequestOptions {
166
+ Path : fullPath ,
167
+ Method : "DELETE" ,
168
+ }
169
+
170
+ _ , err := client .RequestAPI (& opts )
171
+
172
+ if err != nil {
173
+ return err
174
+ }
175
+
176
+ return nil
177
+ }
178
+
179
+ func (client * Client ) DeleteIDPAccount (id string ) error {
180
+
181
+ body , err := EncodeToJSON (map [string ]interface {}{"id" : id })
182
+
183
+ if err != nil {
184
+ return err
185
+ }
186
+
187
+ opts := RequestOptions {
188
+ Path : getAPIEndpoint (false ),
189
+ Method : "DELETE" ,
190
+ Body : body ,
191
+ }
192
+
193
+ _ , err = client .RequestAPI (& opts )
194
+
195
+ if err != nil {
196
+ return err
197
+ }
198
+
199
+ return nil
35
200
}
36
201
37
202
// get all idps
@@ -115,6 +280,22 @@ func (client *Client) GetAccountIDPs() (*[]IDP, error) {
115
280
return & idps , nil
116
281
}
117
282
283
+ func (client * Client ) GetAccountIdpByID (idpID string ) (* IDP , error ) {
284
+
285
+ idpList , err := client .GetAccountIDPs ()
286
+ if err != nil {
287
+ return nil , err
288
+ }
289
+
290
+ for _ , idp := range * idpList {
291
+ if idp .ID == idpID {
292
+ return & idp , nil
293
+ }
294
+ }
295
+
296
+ return nil , errors .New (fmt .Sprintf ("[ERROR] IDP with ID %s isn't found." , idpID ))
297
+ }
298
+
118
299
// add account to idp
119
300
func (client * Client ) AddAccountToIDP (accountId , idpId string ) error {
120
301
0 commit comments