first commit
This commit is contained in:
94
internal/auth/auth.go
Normal file
94
internal/auth/auth.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
|
||||
"git.directme.in/Joren/CanvasArchiver/internal/config"
|
||||
"git.directme.in/Joren/CanvasArchiver/internal/models"
|
||||
)
|
||||
|
||||
type Authenticator struct {
|
||||
HTTPClient *http.Client
|
||||
}
|
||||
|
||||
func NewAuthenticator(client *http.Client) *Authenticator {
|
||||
return &Authenticator{
|
||||
HTTPClient: client,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Authenticator) GetAccessToken() (string, error) {
|
||||
creds, err := LoadCredentials()
|
||||
if err != nil {
|
||||
|
||||
fmt.Println("--- Initial Canvas Login Required ---")
|
||||
fmt.Printf("Visit: %s/login/oauth2/auth?client_id=%s&response_type=code&redirect_uri=%s\n",
|
||||
config.BaseURL, config.ClientID, url.QueryEscape(config.RedirectURI))
|
||||
fmt.Print("Enter Code: ")
|
||||
var code string
|
||||
fmt.Scanln(&code)
|
||||
|
||||
tr, err := a.doTokenRequest(url.Values{
|
||||
"grant_type": {"authorization_code"},
|
||||
"client_id": {config.ClientID},
|
||||
"client_secret": {config.ClientSecret},
|
||||
"redirect_uri": {config.RedirectURI},
|
||||
"code": {code},
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
SaveCredentials(&models.Credentials{RefreshToken: tr.RefreshToken})
|
||||
fmt.Println("[+] Login successful.")
|
||||
return tr.AccessToken, nil
|
||||
}
|
||||
|
||||
fmt.Println("[*] Reusing saved refresh token...")
|
||||
tr, err := a.doTokenRequest(url.Values{
|
||||
"grant_type": {"refresh_token"},
|
||||
"client_id": {config.ClientID},
|
||||
"client_secret": {config.ClientSecret},
|
||||
"refresh_token": {creds.RefreshToken},
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
fmt.Println("[+] Session refreshed.")
|
||||
return tr.AccessToken, nil
|
||||
}
|
||||
|
||||
func (a *Authenticator) doTokenRequest(v url.Values) (*models.TokenResponse, error) {
|
||||
resp, err := a.HTTPClient.PostForm(config.BaseURL+"/login/oauth2/token", v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("token request failed: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
var tr models.TokenResponse
|
||||
json.NewDecoder(resp.Body).Decode(&tr)
|
||||
return &tr, nil
|
||||
}
|
||||
|
||||
func SaveCredentials(creds *models.Credentials) {
|
||||
data, _ := json.MarshalIndent(creds, "", " ")
|
||||
os.WriteFile(config.CredsFile, data, 0o644)
|
||||
}
|
||||
|
||||
func LoadCredentials() (*models.Credentials, error) {
|
||||
data, err := os.ReadFile(config.CredsFile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var creds models.Credentials
|
||||
json.Unmarshal(data, &creds)
|
||||
return &creds, nil
|
||||
}
|
||||
Reference in New Issue
Block a user