Skip to content
This repository has been archived by the owner on May 16, 2021. It is now read-only.

Commit

Permalink
feat: implement CI login
Browse files Browse the repository at this point in the history
  • Loading branch information
mainawycliffe committed Dec 11, 2019
1 parent b27c4ee commit 8b01cf1
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 24 deletions.
34 changes: 34 additions & 0 deletions cmd/login:ci.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package cmd

import (
"fmt"
"os"

"github.com/logrusorgru/aurora"
"github.com/mainawycliffe/kamanda/oauth"
"github.com/spf13/cobra"
)

// loginCICmd represents the login:ci command
var loginCICmd = &cobra.Command{
Use: "login:ci",
Short: "generate an access token for use in non-interactive environments",
Run: func(cmd *cobra.Command, args []string) {
noLocalhostFlag, _ := cmd.Flags().GetBool("no-localhost")
if !noLocalhostFlag {
oauth.LoginWithLocalhost(true)
os.Exit(0)
}
if err := oauth.LoginWithoutLocalhost(true); err != nil {
fmt.Fprint(os.Stdout, aurora.Sprintf(aurora.Red("\n\n%s\n\n"), err.Error()))
os.Exit(1)
}
os.Exit(0)
},
}

func init() {
rootCmd.AddCommand(loginCICmd)
// allow users to login without localhost
loginCICmd.Flags().Bool("no-localhost", false, "copy and paste a code instead of starting a local server for authentication")
}
53 changes: 29 additions & 24 deletions oauth/oauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,19 @@ func getGoogleOAuthConfig(port string) *oauth2.Config {
}
}

func saveRefreshToken(data *GetUserDataFromGoogleResponse) error {
viper.Set(configs.FirebaseRefreshTokenViperConfigKey, data.RefreshToken)
viper.Set(configs.FirebaseLoggedInUserEmailViperConfigKey, data.Email)
err := viper.WriteConfig()
if err != nil {
return fmt.Errorf("An error occurred while saving refresh token: %w", err)
}
return nil
}

// LoginWithLocalhost starts a server that can be used to capture OAUTH
// token from Google Auth Server
func LoginWithLocalhost() {
func LoginWithLocalhost(isCILogin bool) {
googleOauthConfig := getGoogleOAuthConfig(port)
oauthStateTracker := generateOauthStateTracker()
u := googleOauthConfig.AuthCodeURL(oauthStateTracker)
Expand Down Expand Up @@ -156,28 +166,22 @@ func LoginWithLocalhost() {
}
return
}
viper.Set(configs.FirebaseRefreshTokenViperConfigKey, data.RefreshToken)
viper.Set(configs.FirebaseLoggedInUserEmailViperConfigKey, data.Email)
err = viper.WriteConfig()
if err != nil {
fmt.Printf("An error occurred while saving refresh token: %s", err.Error())
if err := writeHTMLOutput(w, templateData, templates.LoginFailureTemplate); err != nil {
fmt.Printf("Error showing response: %s", err.Error())
}
return
}
if err != nil {
log.Println(err.Error())
if err := writeHTMLOutput(w, templateData, templates.LoginFailureTemplate); err != nil {
fmt.Printf("Error showing response: %s", err.Error())
if isCILogin {
fmt.Fprint(os.Stdout, aurora.Sprintf(aurora.Green("\n\nSuccess! Use this token to login on a CI server:\n\n%s"), data.RefreshToken))
fmt.Printf("\n\nExample: firebase deploy --token \"$FIREBASE_TOKEN\"\n")
} else {
if err = saveRefreshToken(data); err != nil {
fmt.Printf("%s", err.Error())
if err := writeHTMLOutput(w, templateData, templates.LoginFailureTemplate); err != nil {
fmt.Printf("Error showing response: %s", err.Error())
}
return
}
return
fmt.Fprint(os.Stdout, aurora.Sprintf(aurora.Green("\n\nSuccess! Logged in as %s\n\n"), data.Email))
}
if err := writeHTMLOutput(w, templateData, templates.LoginSuccessTemplate); err != nil {
fmt.Printf("Error showing response: %s", err.Error())
}
fmt.Fprint(os.Stdout, aurora.Sprintf(aurora.Green("\n\nSuccess! Logged in as %s\n\n"), data.Email))
cancel()
})
go func() {
if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
Expand All @@ -193,7 +197,7 @@ func LoginWithLocalhost() {

// LoginWithoutLocalhost login without localhost localhost server, suitable in
// environments without a GUI. The user enters the authorization code manually
func LoginWithoutLocalhost() error {
func LoginWithoutLocalhost(isCILogin bool) error {
googleOauthConfig := getGoogleOAuthConfig("")
oauthStateTracker := generateOauthStateTracker()
u := googleOauthConfig.AuthCodeURL(oauthStateTracker)
Expand All @@ -210,11 +214,12 @@ func LoginWithoutLocalhost() error {
if err != nil {
return fmt.Errorf("An error occurred while exchanging code with token: %w", err)
}
viper.Set(configs.FirebaseRefreshTokenViperConfigKey, data.RefreshToken)
viper.Set(configs.FirebaseLoggedInUserEmailViperConfigKey, data.Email)
err = viper.WriteConfig()
if err != nil {
return fmt.Errorf("An error occurred while saving refresh token: %w", err)
if isCILogin {
fmt.Fprint(os.Stdout, aurora.Sprintf(aurora.Green("\n\nSuccess! Use this token to login on a CI server:\n\n%s\n"), data.RefreshToken))
return nil
}
if err = saveRefreshToken(data); err != nil {
return err
}
fmt.Fprint(os.Stdout, aurora.Sprintf(aurora.Green("\n\nSuccess! Logged in as %s\n\n"), data.Email))
return nil
Expand Down

0 comments on commit 8b01cf1

Please sign in to comment.