211 lines
5.2 KiB
Go
211 lines
5.2 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"encoding/json"
|
|
"io"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"os"
|
|
|
|
"gitlab.com/khanzf/fedilogue/shared"
|
|
)
|
|
|
|
type OAuth struct {
|
|
Access_token string `"json:access_token"`
|
|
Created_at int `"json:created_at"`
|
|
Expires_in int64 `"json:Expires_in"`
|
|
Refresh_token string `"json:refresh_token"`
|
|
}
|
|
|
|
type authError struct {
|
|
msg string
|
|
}
|
|
|
|
func (e *authError) Error() string {
|
|
return e.msg
|
|
}
|
|
|
|
func register_client(endpoint string, o *shared.RunningInstance) error {
|
|
requestBodymap, _ := json.Marshal(map[string]string{
|
|
"client_name": "Tusky", // Hard-coded in for now...
|
|
"scopes": "read write follow push",
|
|
"redirect_uris": "urn:ietf:wg:oauth:2.0:oob",
|
|
})
|
|
requestBodybytes := bytes.NewBuffer(requestBodymap)
|
|
|
|
api_base_apps := "https://" + endpoint + "/api/v1/apps"
|
|
|
|
resp, err := o.Client.Post(api_base_apps, "application/json", requestBodybytes)
|
|
if err != nil {
|
|
logErr("Unable to connect to "+api_base_apps+" ", err)
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
logErr("Unable to read HTTP response: ", err)
|
|
o.Client_id = ""
|
|
o.Client_secret = ""
|
|
return err
|
|
}
|
|
|
|
bodymap := make(map[string]string)
|
|
err = json.Unmarshal(body, &bodymap)
|
|
if err != nil {
|
|
logErr("Unable to parse response from "+endpoint+": ", err)
|
|
o.Client_id = ""
|
|
o.Client_secret = ""
|
|
return err
|
|
}
|
|
|
|
client_file := "clients/" + endpoint
|
|
|
|
f, err := os.Create("clients/" + endpoint)
|
|
if err != nil {
|
|
logErr("Unable to create "+client_file+": ", err)
|
|
o.Client_id = ""
|
|
o.Client_secret = ""
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
|
|
_, err = io.WriteString(f, bodymap["client_id"]+"\n")
|
|
if err != nil {
|
|
logErr("Unable to write client_id line to file "+client_file+": ", err)
|
|
o.Client_id = bodymap["client_id"]
|
|
o.Client_secret = bodymap["client_secret"]
|
|
return nil
|
|
}
|
|
_, err = io.WriteString(f, bodymap["client_secret"]+"\n")
|
|
if err != nil {
|
|
logErr("Unable to write client_secret to file "+client_file+": ", err)
|
|
o.Client_id = bodymap["client_id"]
|
|
o.Client_secret = bodymap["client_secret"]
|
|
return nil
|
|
}
|
|
|
|
o.Client_id = bodymap["client_id"]
|
|
o.Client_secret = bodymap["client_secret"]
|
|
return nil
|
|
}
|
|
|
|
func get_client(endpoint string, o *shared.RunningInstance) error {
|
|
var err error
|
|
client_file := "clients/" + endpoint
|
|
_, err = os.Stat(client_file)
|
|
if os.IsNotExist(err) == false { // The file exists
|
|
f, err := os.Open(client_file)
|
|
if err != nil {
|
|
logErr("Unable to open " + client_file + ", creating new client")
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
|
|
rd := bufio.NewReader(f)
|
|
|
|
client_id_bin, _, err := rd.ReadLine()
|
|
o.Client_id = string(client_id_bin)
|
|
if err != nil {
|
|
logErr("Unable to read client_id line of " + client_file + ", building new client")
|
|
return err
|
|
}
|
|
client_secret_bin, _, err := rd.ReadLine()
|
|
o.Client_secret = string(client_secret_bin)
|
|
if err != nil {
|
|
logErr("Unable to read client_secret line of " + client_file + ", building new client")
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
} else {
|
|
return register_client(endpoint, o)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func oauth_login(endpoint string, o *shared.RunningInstance, username string, password string) (OAuth, error) {
|
|
authMap, err := json.Marshal(map[string]string{
|
|
"username": username,
|
|
"password": password,
|
|
"redirect_uri": "urn:ietf:wg:oauth:2.0:oob",
|
|
"grant_type": "password",
|
|
"client_name": "Tusky",
|
|
"scope": "read write follow push",
|
|
"client_id": o.Client_id,
|
|
"client_secret": o.Client_secret,
|
|
})
|
|
|
|
if err != nil {
|
|
logErr("Unable to create Authentication map for " + endpoint)
|
|
return OAuth{}, err
|
|
}
|
|
|
|
authMapbytes := bytes.NewBuffer(authMap)
|
|
|
|
resp, err := http.Post("https://"+endpoint+"/oauth/token", "application/json", authMapbytes)
|
|
if err != nil {
|
|
logErr("Cannot connect to "+endpoint+": ", err)
|
|
return OAuth{}, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
logErr("Unable to read response data for "+endpoint+": ", err)
|
|
return OAuth{}, err
|
|
}
|
|
|
|
if resp.StatusCode == 400 {
|
|
logErr("Unable to authenticate to " + endpoint)
|
|
return OAuth{}, &authError{"Authentication error"}
|
|
}
|
|
|
|
oauthData := OAuth{}
|
|
err = json.Unmarshal(body, &oauthData)
|
|
if err != nil {
|
|
logErr("Unable to parse json data for "+endpoint+": ", err)
|
|
return OAuth{}, err
|
|
}
|
|
|
|
return oauthData, nil
|
|
}
|
|
|
|
func oauth_refresh(endpoint string, client_id string, client_secret string, refresh_token string) (OAuth, error) {
|
|
authMap, _ := json.Marshal(map[string]string{
|
|
"redirect_uri": "urn:ietf:wg:oauth:2.0:oob",
|
|
"grant_type": "refresh_token",
|
|
"scope": "read write follow push",
|
|
"refresh_token": refresh_token,
|
|
"client_id": client_id,
|
|
"client_secret": client_secret,
|
|
})
|
|
|
|
authMapbytes := bytes.NewBuffer(authMap)
|
|
|
|
resp, err := http.Post("https://"+endpoint+"/oauth/token", "application/json", authMapbytes)
|
|
if err != nil {
|
|
logErr("Unable to connect to "+endpoint+": ", err)
|
|
return OAuth{}, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
logErr("Unable to read response data for "+endpoint+": ", err)
|
|
return OAuth{}, err
|
|
}
|
|
|
|
oauthData := OAuth{}
|
|
err = json.Unmarshal(body, &oauthData)
|
|
if err != nil {
|
|
logErr("Unable to parse json data for "+endpoint+": ", err)
|
|
return oauthData, err
|
|
}
|
|
|
|
return oauthData, nil
|
|
}
|