From afa975c459947f613ea950ae2927d596918530ca Mon Sep 17 00:00:00 2001 From: bytedream Date: Mon, 16 May 2022 21:21:35 +0200 Subject: [PATCH] Add session id always cached in temp directory (to prevent #30) --- cmd/crunchyroll-go/cmd/login.go | 61 +++++++++++++++++-------- cmd/crunchyroll-go/cmd/utils.go | 81 ++++++++++++++++----------------- 2 files changed, 79 insertions(+), 63 deletions(-) diff --git a/cmd/crunchyroll-go/cmd/login.go b/cmd/crunchyroll-go/cmd/login.go index 5bef2a9..c9fc923 100644 --- a/cmd/crunchyroll-go/cmd/login.go +++ b/cmd/crunchyroll-go/cmd/login.go @@ -5,9 +5,7 @@ import ( "github.com/ByteDream/crunchyroll-go/v2" "github.com/spf13/cobra" "os" - "os/user" "path/filepath" - "runtime" ) var ( @@ -21,11 +19,11 @@ var loginCmd = &cobra.Command{ Short: "Login to crunchyroll", Args: cobra.RangeArgs(1, 2), - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { if loginSessionIDFlag { - loginSessionID(args[0]) + return loginSessionID(args[0]) } else { - loginCredentials(args[0], args[1]) + return loginCredentials(args[0], args[1]) } }, } @@ -46,12 +44,31 @@ func init() { func loginCredentials(user, password string) error { out.Debug("Logging in via credentials") - if _, err := crunchyroll.LoginWithCredentials(user, password, systemLocale(false), client); err != nil { - out.Err(err.Error()) - os.Exit(1) + c, err := crunchyroll.LoginWithCredentials(user, password, systemLocale(false), client) + if err != nil { + return err } - return os.WriteFile(loginStorePath(), []byte(fmt.Sprintf("%s\n%s", user, password)), 0600) + if loginPersistentFlag { + if configDir, err := os.UserConfigDir(); err != nil { + return fmt.Errorf("could not save credentials persistent: %w", err) + } else { + os.MkdirAll(filepath.Join(configDir, "crunchyroll-go"), 0755) + if err = os.WriteFile(filepath.Join(configDir, "crunchyroll-go", "crunchy"), []byte(fmt.Sprintf("%s\n%s", user, password)), 0600); err != nil { + return err + } + out.Info("The login information will be stored permanently UNENCRYPTED on your drive (%s)", filepath.Join(configDir, "crunchyroll-go", "crunchy")) + } + } + if err = os.WriteFile(filepath.Join(os.TempDir(), ".crunchy"), []byte(c.SessionID), 0600); err != nil { + return err + } + + if !loginPersistentFlag { + out.Info("Due to security reasons, you have to login again on the next reboot") + } + + return nil } func loginSessionID(sessionID string) error { @@ -61,21 +78,25 @@ func loginSessionID(sessionID string) error { os.Exit(1) } - return os.WriteFile(loginStorePath(), []byte(sessionID), 0600) -} - -func loginStorePath() string { - path := filepath.Join(os.TempDir(), ".crunchy") + var err error if loginPersistentFlag { - if runtime.GOOS != "windows" { - usr, _ := user.Current() - path = filepath.Join(usr.HomeDir, ".config/crunchy") + if configDir, err := os.UserConfigDir(); err != nil { + return fmt.Errorf("could not save credentials persistent: %w", err) + } else { + os.MkdirAll(filepath.Join(configDir, "crunchyroll-go"), 0755) + if err = os.WriteFile(filepath.Join(configDir, "crunchyroll-go", "crunchy"), []byte(sessionID), 0600); err != nil { + return err + } + out.Info("The login information will be stored permanently UNENCRYPTED on your drive (%s)", filepath.Join(configDir, "crunchyroll-go", "crunchy")) } + } + if err = os.WriteFile(filepath.Join(os.TempDir(), ".crunchy"), []byte(sessionID), 0600); err != nil { + return err + } - out.Info("The login information will be stored permanently UNENCRYPTED on your drive (%s)", path) - } else if runtime.GOOS != "windows" { + if !loginPersistentFlag { out.Info("Due to security reasons, you have to login again on the next reboot") } - return path + return nil } diff --git a/cmd/crunchyroll-go/cmd/utils.go b/cmd/crunchyroll-go/cmd/utils.go index 29a48f7..cafd99d 100644 --- a/cmd/crunchyroll-go/cmd/utils.go +++ b/cmd/crunchyroll-go/cmd/utils.go @@ -8,7 +8,6 @@ import ( "net/url" "os" "os/exec" - "os/user" "path/filepath" "reflect" "regexp" @@ -141,57 +140,53 @@ func freeFileName(filename string) (string, bool) { func loadCrunchy() { out.SetProgress("Logging in") - files := []string{filepath.Join(os.TempDir(), ".crunchy")} - - if runtime.GOOS != "windows" { - usr, _ := user.Current() - files = append(files, filepath.Join(usr.HomeDir, ".config/crunchy")) - } - - var err error - for _, file := range files { - if _, err = os.Stat(file); os.IsNotExist(err) { - err = nil - continue - } - var body []byte - if body, err = os.ReadFile(file); err != nil { - out.StopProgress("Failed to read login information: %v", err) - os.Exit(1) - } else if body == nil { - continue - } - - split := strings.SplitN(string(body), "\n", 2) - if len(split) == 1 || split[1] == "" { - if crunchy, err = crunchyroll.LoginWithSessionID(split[0], systemLocale(true), client); err == nil { - out.Debug("Logged in with session id %s. BLANK THIS LINE OUT IF YOU'RE ASKED TO POST THE DEBUG OUTPUT SOMEWHERE", split[0]) + if configDir, err := os.UserConfigDir(); err == nil { + persistentFilePath := filepath.Join(configDir, "crunchyroll-go", "crunchy") + if _, statErr := os.Stat(persistentFilePath); statErr == nil { + body, err := os.ReadFile(persistentFilePath) + if err != nil { + out.StopProgress("Failed to read login information: %v", err) + os.Exit(1) } - } else { - if crunchy, err = crunchyroll.LoginWithCredentials(split[0], split[1], systemLocale(true), client); err != nil { - continue - } - out.Debug("Logged in with username '%s' and password '%s'. BLANK THIS LINE OUT IF YOU'RE ASKED TO POST THE DEBUG OUTPUT SOMEWHERE", split[0], split[1]) - if file != filepath.Join(os.TempDir(), ".crunchy") { - // the session id is written to a temp file to reduce the amount of re-logging in. - // it seems like that crunchyroll has also a little cooldown if a user logs in too often in a short time - if err = os.WriteFile(filepath.Join(os.TempDir(), ".crunchy"), []byte(crunchy.SessionID), 0600); err != nil { - out.StopProgress("Failed to write session id to temp file") + split := strings.SplitN(string(body), "\n", 2) + if len(split) == 1 || split[1] == "" { + split[0] = url.QueryEscape(split[0]) + if crunchy, err = crunchyroll.LoginWithSessionID(split[0], systemLocale(true), client); err != nil { + out.StopProgress(err.Error()) os.Exit(1) } - out.Debug("Wrote session id to temp file") + out.Debug("Logged in with session id %s. BLANK THIS LINE OUT IF YOU'RE ASKED TO POST THE DEBUG OUTPUT SOMEWHERE", split[0]) + } else { + if crunchy, err = crunchyroll.LoginWithCredentials(split[0], split[1], systemLocale(true), client); err != nil { + out.StopProgress(err.Error()) + os.Exit(1) + } + out.Debug("Logged in with session id %s. BLANK THIS LINE OUT IF YOU'RE ASKED TO POST THE DEBUG OUTPUT SOMEWHERE", crunchy.SessionID) + // the session id is written to a temp file to reduce the amount of re-logging in. + // it seems like that crunchyroll has also a little cooldown if a user logs in too often in a short time + os.WriteFile(filepath.Join(os.TempDir(), ".crunchy"), []byte(crunchy.SessionID), 0600) } + return + } + } + + tmpFilePath := filepath.Join(os.TempDir(), ".crunchy") + if _, statErr := os.Stat(tmpFilePath); !os.IsNotExist(statErr) { + body, err := os.ReadFile(tmpFilePath) + if err != nil { + out.StopProgress("Failed to read login information: %v", err) + os.Exit(1) + } + if crunchy, err = crunchyroll.LoginWithSessionID(url.QueryEscape(string(body)), systemLocale(true), client); err != nil { + out.StopProgress(err.Error()) + os.Exit(1) } - out.StopProgress("Logged in") + out.Debug("Logged in with session id %s. BLANK THIS LINE OUT IF YOU'RE ASKED TO POST THE DEBUG OUTPUT SOMEWHERE", body) return } - if err != nil { - out.StopProgress(err.Error()) - } else { - out.StopProgress("To use this command, login first. Type `%s login -h` to get help", os.Args[0]) - } + out.StopProgress("To use this command, login first. Type `%s login -h` to get help", os.Args[0]) os.Exit(1) }