diff options
-rw-r--r-- | README.org | 14 | ||||
-rw-r--r-- | authconf.go | 13 | ||||
-rw-r--r-- | main.go | 45 | ||||
-rw-r--r-- | main_test.go | 10 | ||||
-rw-r--r-- | oauth.go | 22 | ||||
-rw-r--r-- | secrets.go | 38 | ||||
-rw-r--r-- | token.go | 20 |
7 files changed, 65 insertions, 97 deletions
diff --git a/README.org b/README.org index 7a8faf3..2cff1a0 100644 --- a/README.org +++ b/README.org @@ -2,3 +2,17 @@ * Lifesigns A CLI for status applications that shows live followed streamers + +~'secrets' File not found, Check the README~: +- Create the file ~"~~/.local/share/lifesigns/secrets"~ +- Populate it with 2 lines being your registered Twitch app's ClientID and ClientSecret + #+begin_src + clientid + clientsecret + #+end_src + +** TODO +- Finish this README +- User should only interact with a config in .config/lifesigns +- Add -h/--help for otf configuration +- Replace Error panics with sending up the chain to Main diff --git a/authconf.go b/authconf.go index 2e9b81b..2a59392 100644 --- a/authconf.go +++ b/authconf.go @@ -22,16 +22,14 @@ func Auth(authFile string) UTRSimple { } func WriteAuth(authFile string) { - authToken, err := GetOAuth(clientID) + authToken, err := GetOAuth() if err != nil { panic(err) } uT := GetUserToken(authToken) - err = os.MkdirAll("/home/venomade/.local/share/lifesigns", 0755) - // TODO: unhardcode - + err = os.MkdirAll(dataDir, 0755) if err != nil { panic(err) } @@ -42,7 +40,7 @@ func WriteAuth(authFile string) { } defer file.Close() - confString := fmt.Sprintf("%s\n%s\n%s", uT.AccessToken, uT.ExpiresIn, uT.RefreshToken) + confString := fmt.Sprintf("%s\n%d\n%s", uT.AccessToken, uT.ExpiresIn, uT.RefreshToken) _, err = file.WriteString(confString) if err != nil { panic(err) @@ -57,10 +55,8 @@ func ReadAuth(authFile string) UTRSimple{ } defer file.Close() - // Create a slice to hold the lines of the file var lines []string - // Read all lines from the file into the slice scanner := bufio.NewScanner(file) for scanner.Scan() { lines = append(lines, scanner.Text()) @@ -68,8 +64,7 @@ func ReadAuth(authFile string) UTRSimple{ var utrs UTRSimple - // Process each line using the appropriate function - if len(lines) >= 2 { // Change to 3 + if len(lines) >= 3 { utrs.AccessToken = lines[0] exp, _ := strconv.Atoi(lines[1]) utrs.ExpiresIn = exp diff --git a/main.go b/main.go index 462cd96..f0f40a2 100644 --- a/main.go +++ b/main.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "os" "strings" "github.com/nicklaw5/helix/v2" @@ -9,23 +10,22 @@ import ( "golang.org/x/oauth2/clientcredentials" ) +const DEBUG bool = false +const USERNAME string = "venomade98" // TODO: Make configurable + var ( - clientSecrets = Secrets("/home/venomade/.local/share/lifesigns/secrets") - clientID = clientSecrets.ClientID - clientSecret = clientSecrets.ClientSecret // Refactor - authFile = "/home/venomade/.local/share/lifesigns/auth" - secretsFile = "/home/venomade/.local/share/lifesigns/secrets" + dataDir = fmt.Sprintf("%s/.local/share/lifesigns", os.Getenv("HOME")) + clientSecrets = Secrets(fmt.Sprintf("%s/secrets", dataDir)) // Fix Hardcodes oauth2Config *clientcredentials.Config ) func main() { - - userTokens := Auth(authFile); + userTokens := Auth(fmt.Sprintf("%s/auth", dataDir)); client, err := helix.NewClient(&helix.Options{ - ClientID: clientID, - ClientSecret: clientSecret, + ClientID: clientSecrets.ClientID, + ClientSecret: clientSecrets.ClientSecret, AppAccessToken: GetAppToken(), UserAccessToken: userTokens.AccessToken, RefreshToken: userTokens.RefreshToken, @@ -34,25 +34,10 @@ func main() { panic(err) } - // resp, err := client.GetUsers(&helix.UsersParams{ - // IDs: []string{"26301881", "18074328"}, - // Logins: []string{"summit1g", "lirik"}, - // }) - - // resp, err := client.GetFollowedStream(&helix.FollowedStreamsParams{ - // UserID: "venomade98", - // }) - // resp, err := client.GetFollowedChannels(&helix.GetFollowedChannelParams{ - // UserID: GetUserID(client), - // }) - resp, err := client.GetFollowedStream(&helix.FollowedStreamsParams{ UserID: GetUserID(client), }) - // for _, channel := range resp.Data.FollowedChannels { - // fmt.Println("Channel:", channel.BroadcasterName) - // } var output strings.Builder for _, channel := range resp.Data.Streams { @@ -71,11 +56,13 @@ func GetUserID(client *helix.Client) string{ panic(err) } - // fmt.Printf("Status code: %d\n", resp.StatusCode) - // fmt.Printf("Error: %s\n", resp.ErrorMessage) - // fmt.Printf("Rate limit: %d\n", resp.GetRateLimit()) - // fmt.Printf("Rate limit remaining: %d\n", resp.GetRateLimitRemaining()) - // fmt.Printf("Rate limit reset: %d\n\n", resp.GetRateLimitReset()) + if DEBUG { + fmt.Printf("Status code: %d\n", resp.StatusCode) + fmt.Printf("Error: %s\n", resp.ErrorMessage) + fmt.Printf("Rate limit: %d\n", resp.GetRateLimit()) + fmt.Printf("Rate limit remaining: %d\n", resp.GetRateLimitRemaining()) + fmt.Printf("Rate limit reset: %d\n\n", resp.GetRateLimitReset()) + } var uid string; diff --git a/main_test.go b/main_test.go index a9386d0..7e106fd 100644 --- a/main_test.go +++ b/main_test.go @@ -7,7 +7,10 @@ import ( ) func TestOAuth(t *testing.T) { - result := GetOAuth(clientID, "/home/venomade/.local/share/lifesigns/auth") + result, err := GetOAuth() + if err != nil { + t.Error(err) + } if result != "" { fmt.Println("OAuth: ", result) } else { @@ -17,7 +20,10 @@ func TestOAuth(t *testing.T) { func TestOAuthNoFile(t *testing.T) { os.Remove("/home/venomade/.local/share/lifesigns/auth") - result := GetOAuth(clientID, "/home/venomade/.local/share/lifesigns/auth") + result, err := GetOAuth() + if err != nil { + t.Error(err) + } if result != "" { fmt.Println("OAuth: ", result) } else { diff --git a/oauth.go b/oauth.go index f41dde3..e3f4174 100644 --- a/oauth.go +++ b/oauth.go @@ -12,46 +12,42 @@ func openBrowser(url string) error { } func startServer(codeChannel chan string) { - // Step 5: Start a web server that listens on localhost:3000 http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - // Extract the code parameter from the query string code := r.URL.Query().Get("code") if code != "" { - // Send the authorization code to the channel codeChannel <- code - // Respond to the browser fmt.Fprintf(w, "Authorization successful! You can now close this window.") } else { - // If there's no code, display an error http.Error(w, "Authorization failed", http.StatusBadRequest) } }) - // Start the server err := http.ListenAndServe(":3000", nil) if err != nil { fmt.Printf("Error starting server: %v\n", err) } } -func GetOAuth(clientID string) (string, error) { - // Step 1: Construct the URL with the provided client_id - url := fmt.Sprintf("https://id.twitch.tv/oauth2/authorize?response_type=code&client_id=%s&redirect_uri=http://localhost:3000&scope=user%%3Aread%%3Afollows&state=xsscheckbasic101", clientID) +func GetOAuth() (string, error) { + url := fmt.Sprintf("%s?%s&%s&%s&%s&%s", + "https://id.twitch.tv/oauth2/authorize", + "response_type=code", + fmt.Sprintf("client_id=%s", clientSecrets.ClientID), + "redirect_uri=http://localhost:3000", + "scope=user%3Aread%3Afollows", + "state=xsscheckbasic101", + ) - // Step 2: Open the URL in the default web browser using xdg-open err := openBrowser(url) if err != nil { return "", fmt.Errorf("failed to open browser: %v", err) } - // Step 3: Start the HTTP server to capture the response codeChannel := make(chan string) go startServer(codeChannel) - // Step 4: Wait for the authorization code to be received code := <-codeChannel - // Return the authorization code return code, nil } diff --git a/secrets.go b/secrets.go index e8f3762..378b8c0 100644 --- a/secrets.go +++ b/secrets.go @@ -14,39 +14,16 @@ type SecretsConf struct { func Secrets(secretsFile string) SecretsConf { _, ferr := os.Stat(secretsFile) if ferr != nil { - // WriteSecrets(secretsFile) + err := os.MkdirAll(dataDir, 0755) + if err != nil { + panic(err) + } + fmt.Println("'secrets' File not found, Check the README") + os.Exit(1) } return ReadSecrets(secretsFile) } -// func WriteSecrets(secretsFile string) { -// secretsToken, err := GetOAuth(clientID) -// if err != nil { -// panic(err) -// } - -// uT := GetUserToken(secretsToken) - -// err = os.MkdirAll("/home/venomade/.local/share/lifesigns", 0755) -// // TODO: unhardcode - -// if err != nil { -// panic(err) -// } - -// file, err := os.Create(secretsFile) -// if err != nil { -// panic(err) -// } -// defer file.Close() - -// confString := fmt.Sprintf("%s\n%s\n%s", uT.AccessToken, uT.ExpiresIn, uT.RefreshToken) -// _, err = file.WriteString(confString) -// if err != nil { -// panic(err) -// } -// } - func ReadSecrets(secretsFile string) SecretsConf { file, err := os.Open(secretsFile) if err != nil { @@ -55,10 +32,8 @@ func ReadSecrets(secretsFile string) SecretsConf { } defer file.Close() - // Create a slice to hold the lines of the file var lines []string - // Read all lines from the file into the slice scanner := bufio.NewScanner(file) for scanner.Scan() { lines = append(lines, scanner.Text()) @@ -66,7 +41,6 @@ func ReadSecrets(secretsFile string) SecretsConf { var secrets SecretsConf - // Process each line using the appropriate function if len(lines) >= 2 { secrets.ClientID = lines[0] secrets.ClientSecret = lines[1] diff --git a/token.go b/token.go index 8ccbdb2..73089cd 100644 --- a/token.go +++ b/token.go @@ -24,27 +24,23 @@ type UserTokenResponse struct { func GetUserToken(authCode string) UserTokenResponse{ - // Define the URL and form data - apiURL := "https://id.twitch.tv/oauth2/token" // Replace with the actual URL to send the POST request to + apiURL := "https://id.twitch.tv/oauth2/token" data := url.Values{} - data.Set("client_id", clientID) - data.Set("client_secret", clientSecret) + data.Set("client_id", clientSecrets.ClientID) + data.Set("client_secret", clientSecrets.ClientSecret) data.Set("code", authCode) data.Set("grant_type", "authorization_code") data.Set("redirect_uri", "http://localhost:3000") - // Create the POST request req, err := http.NewRequest("POST", apiURL, bytes.NewBufferString(data.Encode())) if err != nil { fmt.Println("Error creating request:", err) panic(err) } - // Set the appropriate header for x-www-form-urlencoded req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - // Send the request client := &http.Client{} resp, err := client.Do(req) if err != nil { @@ -53,10 +49,10 @@ func GetUserToken(authCode string) UserTokenResponse{ } defer resp.Body.Close() - // Print the response status - // fmt.Println("Response Status:", resp.Status) + if DEBUG { + fmt.Println("Response Status:", resp.Status) + } - // You can read and print the body here if needed body, err := io.ReadAll(resp.Body) if err != nil { fmt.Println("Error reading response body:", err) @@ -76,8 +72,8 @@ func GetUserToken(authCode string) UserTokenResponse{ func GetAppToken() string{ oauth2Config = &clientcredentials.Config{ - ClientID: clientID, - ClientSecret: clientSecret, + ClientID: clientSecrets.ClientID, + ClientSecret: clientSecrets.ClientSecret, TokenURL: twitch.Endpoint.TokenURL, } |