First commit

This commit is contained in:
webb 2020-07-19 07:36:27 -04:00
commit 74099b7ac2
No known key found for this signature in database
GPG Key ID: 8B6F0D2784D22DB2
4 changed files with 226 additions and 0 deletions

113
account.go Normal file
View File

@ -0,0 +1,113 @@
package teal
import (
"bytes"
"encoding/json"
"errors"
"io/ioutil"
"log"
"net/http"
)
// User holds all of the information about a user that is accessible from the profile page
type User struct {
ID int `json:"id"`
Username string `json:"username"`
Email string `json:"Email"`
RegistrationDate string `json:"registrationDate"`
LastLogin string `json:"lastLogin"`
UploadKey string `json:"uploadKey"`
RegistrationIP string `json:"registrationIp"`
Moderator bool `json:"moderator"`
Admin bool `json:"admin"`
Banned bool `json:"banned"`
BanReason string `json:"banReason"`
ImageCount int `json:"imageCount"`
}
// UpdateAccountInfo is a wrapper for GetAccountInfo() that replaces user info automatically
func (c Client) UpdateAccountInfo() error {
u, err := GetAccountInfo(c.Session)
if err != nil {
return err
}
c.User = u
return nil
}
// GetAccountInfo gets info of a user of a given authenticated session
func GetAccountInfo(session string) (User, error) {
httpClient := &http.Client{}
req, err := http.NewRequest("GET", "https://api.pxl.blue/users/@me", nil)
req.Header.Set("Authorization", session)
if err != nil {
log.Println(err)
return User{}, err
}
resp, err := httpClient.Do(req)
if err != nil {
log.Println(err)
return User{}, err
}
if resp != nil {
defer resp.Body.Close()
}
bodyReader, err := ioutil.ReadAll(resp.Body)
if err != nil {
return User{}, err
}
var uR userResponse
err = json.Unmarshal(bodyReader, &uR)
if err != nil {
{
return User{}, err
}
}
return uR.User, nil
}
// Gets session from given username and password
func getSession(u string, p string) (string, error) {
rb, err := json.Marshal(map[string]string{
"username": u,
"password": p,
})
if err != nil {
return "", err
}
rs, err := http.Post("https://api.pxl.blue/auth/login", "application/json", bytes.NewBuffer(rb))
if err != nil {
return "", err
}
body, err := ioutil.ReadAll(rs.Body)
if err != nil {
return "", err
}
defer rs.Body.Close()
var lr loginResponse
err = json.Unmarshal(body, &lr)
if err != nil {
log.Println(err)
return "", err
}
if !lr.Success {
log.Println(err)
return "", errors.New(lr.Message)
}
if err != nil {
log.Println(err)
return "", err
}
defer rs.Body.Close()
return lr.Session, nil
}

30
client.go Normal file
View File

@ -0,0 +1,30 @@
package teal
// Client represents the client used for making http requests, including the session if used.
type Client struct {
UploadKey string
Session string
UserAgent string
User User
}
// Login will login to an account with the provided credentials and give you a Client with user info back
func Login(username string, password string) (Client, error) {
s, err := getSession(username, password)
if err != nil {
return Client{}, err
}
u, err := GetAccountInfo(s)
if err != nil {
return Client{}, err
}
var client Client
client.User = u
client.Session = s
client.UploadKey = u.UploadKey
client.UserAgent = "teal"
return client, nil
}

40
http.go Normal file
View File

@ -0,0 +1,40 @@
/* HTTP related structs and helpers */
package teal
import (
"fmt"
"io"
"mime/multipart"
"net/textproto"
"strings"
)
var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")
type loginResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
Session string `json:"session"`
}
type userResponse struct {
Success bool `json:"success"`
Message string `json:"message"`
User User `json:"user"`
}
/* createFormFileWithMIME is a modification of multipart.CreateFormFile() that
allows arbitrary mime-types. */
func createFormFileWithMIME(w *multipart.Writer, fieldname, filename string, mimeType string) (io.Writer, error) {
h := make(textproto.MIMEHeader)
h.Set("Content-Disposition",
fmt.Sprintf(`form-data; name="%s"; filename="%s"`,
escapeQuotes(fieldname), escapeQuotes(filename)))
h.Set("Content-Type", mimeType)
return w.CreatePart(h)
}
func escapeQuotes(s string) string {
return quoteEscaper.Replace(s)
}

43
upload.go Normal file
View File

@ -0,0 +1,43 @@
package teal
import (
"io"
"io/ioutil"
"mime"
"mime/multipart"
"net/http"
"path/filepath"
)
// UploadFile attempts to upload file from io.Readerm and returns the response
func (c Client) UploadFile(rd io.Reader, n string) (response string, error error) {
r, w := io.Pipe()
m := multipart.NewWriter(w)
go func() {
defer w.Close()
defer m.Close()
part, err := createFormFileWithMIME(m, "file", n, mime.TypeByExtension(filepath.Ext(n)))
if err != nil {
return
}
if err != nil {
return
}
if _, err = io.Copy(part, rd); err != nil {
return
}
m.WriteField("key", c.UploadKey)
}()
rs, err := http.Post("https://api.pxl.blue/upload/sharex", m.FormDataContentType(), r)
if err != nil {
return "", err
}
rb, err := ioutil.ReadAll(rs.Body)
if err != nil {
return "", err
}
return string(rb), err
}