Skip to content
This repository was archived by the owner on Mar 25, 2025. It is now read-only.

improve auth analytics #285

Merged
2 commits merged into from
Feb 24, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/klotho/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ func (local *LocalAuth) SetUpCliFlags(flags *pflag.FlagSet) {
flags.BoolVar((*bool)(local), "local", bool(*local), "If provided, runs Klotho with a local login (that is, not requiring an authenticated login)")
}

func (local *LocalAuth) Authorize() (*auth.KlothoClaims, error) {
func (local *LocalAuth) Authorize() (auth.LoginInfo, error) {
if !*local {
return auth.Authorize()
}
return nil, nil
return auth.LoginInfo{Authorizer: "local"}, nil
}
10 changes: 7 additions & 3 deletions pkg/analytics/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,14 @@ func NewClient() *Client {
return client
}

func (t *Client) AttachAuthorizations(claims *auth.KlothoClaims) {
func (t *Client) AttachAuthorizations(loginInfo auth.LoginInfo) {
t.universalProperties["localId"] = t.userId
t.userId = claims.Email
t.universalProperties["validated"] = claims.EmailVerified

if loginInfo.Email != "" {
t.userId = loginInfo.Email
t.universalProperties["validated"] = loginInfo.EmailVerified
}
t.universalProperties["loginMethod"] = loginInfo.Authorizer
}

func (t *Client) Info(event string) {
Expand Down
30 changes: 22 additions & 8 deletions pkg/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type LoginResponse struct {

type Auth0Authorizer struct{}

func (s Auth0Authorizer) Authorize() (*KlothoClaims, error) {
func (s Auth0Authorizer) Authorize() (LoginInfo, error) {
return Authorize()
}

Expand Down Expand Up @@ -154,7 +154,7 @@ func CallRefreshToken(token string) error {
return nil
}

type KlothoClaims struct {
type klothoClaims struct {
ProEnabled bool
ProTier int
Email string `json:"email"`
Expand All @@ -163,11 +163,25 @@ type KlothoClaims struct {
jwt.RegisteredClaims
}

func Authorize() (*KlothoClaims, error) {
return authorize(false)
type LoginInfo struct {
Authorizer string
Email string
EmailVerified bool
}

func authorize(tokenRefreshed bool) (*KlothoClaims, error) {
func Authorize() (LoginInfo, error) {
claims, err := authorize(false)
loginInfo := LoginInfo{
Authorizer: "auth0",
}
if claims != nil {
loginInfo.Email = claims.Email
loginInfo.EmailVerified = claims.EmailVerified
}
return loginInfo, err
}

func authorize(tokenRefreshed bool) (*klothoClaims, error) {
creds, claims, err := getClaims()
if err != nil {
return nil, err
Expand Down Expand Up @@ -203,18 +217,18 @@ func authorize(tokenRefreshed bool) (*KlothoClaims, error) {
return claims, nil
}

func getClaims() (*Credentials, *KlothoClaims, error) {
func getClaims() (*Credentials, *klothoClaims, error) {
creds, err := GetIDToken()
if err != nil {
return nil, nil, err
}
token, err := jwt.ParseWithClaims(creds.IdToken, &KlothoClaims{}, func(token *jwt.Token) (interface{}, error) {
token, err := jwt.ParseWithClaims(creds.IdToken, &klothoClaims{}, func(token *jwt.Token) (interface{}, error) {
return getPem()
})
if err != nil {
return nil, nil, err
}
if claims, ok := token.Claims.(*KlothoClaims); ok {
if claims, ok := token.Claims.(*klothoClaims); ok {
return creds, claims, nil
} else {
return nil, nil, err
Expand Down
10 changes: 4 additions & 6 deletions pkg/cli/klothomain.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ type KlothoMain struct {
}
type Authorizer interface {

// Authorize tries to authorize the user. The KlothoClaims it returns may be nil, even if the authentication
// succeeds. Conversely, if the KlothoClaims is non-nil, it is valid even if the error is also non-nil; you can use
// Authorize tries to authorize the user. The klothoClaims it returns may be nil, even if the authentication
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Authorize tries to authorize the user. The klothoClaims it returns may be nil, even if the authentication
// Authorize tries to authorize the user. The `LoginInfo` it returns may be nil, even if the authentication

// succeeds. Conversely, if the klothoClaims is non-nil, it is valid even if the error is also non-nil; you can use
// those claims provisionally (and specifically, in analytics) even if the error is non-nil, indicating failed
// authentication.
Authorize() (*auth.KlothoClaims, error)
Authorize() (auth.LoginInfo, error)
}

type FlagsProvider interface {
Expand Down Expand Up @@ -314,9 +314,7 @@ func (km KlothoMain) run(cmd *cobra.Command, args []string) (err error) {

// Needs to go after the --version and --update checks
claims, err := km.Authorizer.Authorize()
if claims != nil {
analyticsClient.AttachAuthorizations(claims)
}
analyticsClient.AttachAuthorizations(claims)
if err != nil {
if errors.Is(err, auth.ErrNoCredentialsFile) {
return errors.New(`Failed to get credentials for user. Please run "klotho --login"`)
Expand Down