-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d45a748
commit 5ca97b7
Showing
18 changed files
with
821 additions
and
330 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package authentication | ||
|
||
import ( | ||
"fmt" | ||
"github.com/elasticpath/epcc-cli/config" | ||
log "github.com/sirupsen/logrus" | ||
"net/url" | ||
"time" | ||
) | ||
|
||
func InternalImplicitAuthentication(args []string) error { | ||
values := url.Values{} | ||
values.Set("grant_type", "implicit") | ||
|
||
env := config.GetEnv() | ||
if len(args) == 0 { | ||
log.Debug("Arguments have been passed, not using profile EPCC_CLIENT_ID") | ||
values.Set("client_id", env.EPCC_CLIENT_ID) | ||
} | ||
|
||
if len(args)%2 != 0 { | ||
return fmt.Errorf("invalid number of arguments supplied to login command, must be multiple of 2, not %v", len(args)) | ||
} | ||
|
||
for i := 0; i < len(args); i += 2 { | ||
k := args[i] | ||
values.Set(k, args[i+1]) | ||
} | ||
|
||
token, err := GetAuthenticationToken(false, &values, true) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
if token != nil { | ||
log.Infof("Successfully authenticated with implicit token, session expires %s", time.Unix(token.Expires, 0).Format(time.RFC1123Z)) | ||
} else { | ||
log.Warn("Did not successfully authenticate against the API") | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package oidc | ||
|
||
import ( | ||
"context" | ||
"encoding/base64" | ||
gojson "encoding/json" | ||
"fmt" | ||
"github.com/elasticpath/epcc-cli/external/authentication" | ||
"github.com/elasticpath/epcc-cli/external/httpclient" | ||
"github.com/elasticpath/epcc-cli/external/rest" | ||
"net/http" | ||
) | ||
|
||
type CallbackPageInfo struct { | ||
LoginType string | ||
ErrorTitle string | ||
ErrorDescription string | ||
AccountTokenResponse *authentication.AccountManagementAuthenticationTokenResponse | ||
AccountTokenStructBase64 []string | ||
} | ||
|
||
func GetCallbackData(ctx context.Context, port uint16, r *http.Request) (*CallbackPageInfo, error) { | ||
// Parse the query parameters | ||
queryParams := r.URL.Query() | ||
|
||
// Convert query parameters to a map | ||
data := make(map[string]string) | ||
for key, values := range queryParams { | ||
data[key] = values[0] // Use the first value if multiple are provided | ||
} | ||
|
||
data["uri"] = fmt.Sprintf("http://localhost:", port) | ||
|
||
if data["code"] != "" { | ||
|
||
state, err := r.Cookie("state") | ||
|
||
if err != nil { | ||
return nil, fmt.Errorf("could not get state cookie: %w", err) | ||
} | ||
|
||
verifier, err := r.Cookie("code_verifier") | ||
|
||
if err != nil { | ||
return nil, fmt.Errorf("could not get verifier cookie: %w", err) | ||
} | ||
|
||
result, err := rest.CreateInternal(context.Background(), &httpclient.HttpParameterOverrides{}, []string{"account-management-authentication-token", | ||
"authentication_mechanism", "oidc", | ||
"oauth_authorization_code", data["code"], | ||
"oauth_redirect_uri", fmt.Sprintf("http://localhost:%d/callback", port), | ||
"oauth_state", state.Value, | ||
"oauth_code_verifier", verifier.Value, | ||
}, false, "", true) | ||
|
||
if err != nil { | ||
return nil, fmt.Errorf("could not get account tokens: %w", err) | ||
} | ||
|
||
cpi := CallbackPageInfo{ | ||
LoginType: "AM", | ||
} | ||
|
||
err = gojson.Unmarshal([]byte(result), &cpi.AccountTokenResponse) | ||
|
||
if err != nil { | ||
return nil, fmt.Errorf("could not unmarshal response: %w", err) | ||
} | ||
|
||
for _, v := range cpi.AccountTokenResponse.Data { | ||
|
||
str, err := gojson.Marshal(v) | ||
|
||
if err != nil { | ||
return nil, fmt.Errorf("could not encode token: %w", err) | ||
} | ||
|
||
base64.URLEncoding.EncodeToString(str) | ||
|
||
cpi.AccountTokenStructBase64 = append(cpi.AccountTokenStructBase64, base64.URLEncoding.EncodeToString(str)) | ||
} | ||
|
||
return &cpi, nil | ||
} else if data["error"] == "" { | ||
|
||
return &CallbackPageInfo{ | ||
ErrorTitle: "Bad Response", | ||
ErrorDescription: "Invalid response from IdP, no code or error query parameter", | ||
}, nil | ||
} else { | ||
return &CallbackPageInfo{ | ||
ErrorTitle: data["error"], | ||
ErrorDescription: data["error_description"], | ||
}, nil | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
package oidc | ||
|
||
import ( | ||
"context" | ||
"encoding/base64" | ||
gojson "encoding/json" | ||
"fmt" | ||
"github.com/elasticpath/epcc-cli/external/authentication" | ||
log "github.com/sirupsen/logrus" | ||
"net/http" | ||
"os" | ||
"time" | ||
) | ||
|
||
type TokenPageInfo struct { | ||
LoginType string | ||
ErrorTitle string | ||
ErrorDescription string | ||
Name string | ||
Id string | ||
} | ||
|
||
func GetTokenData(ctx context.Context, port uint16, r *http.Request) (*TokenPageInfo, error) { | ||
// Parse the query parameters | ||
queryParams := r.URL.Query() | ||
|
||
// Convert query parameters to a map | ||
data := make(map[string]string) | ||
for key, values := range queryParams { | ||
data[key] = values[0] // Use the first value if multiple are provided | ||
} | ||
|
||
if data["login_type"] == "AM" { | ||
token := data["token"] | ||
amTokenJson, err := base64.URLEncoding.DecodeString(token) | ||
|
||
if err != nil { | ||
return nil, fmt.Errorf("could not get decode am token: %w", err) | ||
} | ||
|
||
amToken := authentication.AccountManagementAuthenticationTokenStruct{} | ||
|
||
err = gojson.Unmarshal(amTokenJson, &amToken) | ||
|
||
if err != nil { | ||
return nil, fmt.Errorf("could not get unmarshal am token: %w", err) | ||
} | ||
|
||
authentication.SaveAccountManagementAuthenticationToken(amToken) | ||
|
||
apiToken := authentication.GetApiToken() | ||
|
||
if apiToken != nil { | ||
if apiToken.Identifier == "client_credentials" { | ||
log.Warnf("You are currently logged in with client_credentials, please switch to implicit with `epcc login implicit` to use the account management token correctly. Mixing client_credentials and the account management token can lead to unintended results.") | ||
} | ||
} | ||
|
||
go func() { | ||
time.Sleep(2 * time.Second) | ||
log.Infof("Authentication complete, shutting down") | ||
os.Exit(0) | ||
}() | ||
|
||
return &TokenPageInfo{ | ||
LoginType: "AM", | ||
Name: amToken.AccountName, | ||
Id: amToken.AccountId, | ||
}, nil | ||
|
||
} | ||
|
||
return nil, fmt.Errorf("invalid login type") | ||
} |
Oops, something went wrong.