112 lines
2.7 KiB
Go
112 lines
2.7 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"errors"
|
||
|
"io/ioutil"
|
||
|
"net/http"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
type ContentType int
|
||
|
|
||
|
const (
|
||
|
WwwForm ContentType = iota
|
||
|
Json
|
||
|
Multipart
|
||
|
UnsupportedType
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
indieAuthTokenUrl = "https://tokens.indieauth.com/token"
|
||
|
)
|
||
|
|
||
|
type IndieAuthRes struct {
|
||
|
Me string `json:"me"`
|
||
|
ClientId string `json:"client_id"`
|
||
|
Scope string `json:"scope"`
|
||
|
Issue int `json:"issued_at"`
|
||
|
Nonce int `json:"nonce"`
|
||
|
}
|
||
|
|
||
|
func checkAccess(token string) (bool, error) {
|
||
|
if token == "" {
|
||
|
return false, errors.New("token string is empty")
|
||
|
}
|
||
|
// form the request to check the token
|
||
|
client := &http.Client{}
|
||
|
req, err := http.NewRequest("GET", indieAuthTokenUrl, nil)
|
||
|
if err != nil {
|
||
|
return false, errors.New("error making the request for checking token access")
|
||
|
}
|
||
|
req.Header.Set("Accept", "application/json")
|
||
|
req.Header.Set("Authorization", token)
|
||
|
// send the request
|
||
|
res, err := client.Do(req)
|
||
|
if err != nil {
|
||
|
return false, errors.New("error sending the request for checking token access")
|
||
|
}
|
||
|
defer res.Body.Close()
|
||
|
// parse the response
|
||
|
body, err := ioutil.ReadAll(res.Body)
|
||
|
if err != nil {
|
||
|
return false, errors.New("error parsing the response for checking token access")
|
||
|
}
|
||
|
var indieAuthRes = new(IndieAuthRes)
|
||
|
err = json.Unmarshal(body, &indieAuthRes)
|
||
|
if err != nil {
|
||
|
return false, errors.New("Error parsing the response into json for checking token access " + err.Error())
|
||
|
}
|
||
|
// verify results of the response
|
||
|
blogURL, err := GetBlogURL()
|
||
|
if err != nil {
|
||
|
return false, err
|
||
|
}
|
||
|
if indieAuthRes.Me != blogURL {
|
||
|
return false, errors.New("me does not match")
|
||
|
}
|
||
|
scopes := strings.Fields(indieAuthRes.Scope)
|
||
|
postPresent := false
|
||
|
for _, scope := range scopes {
|
||
|
if scope == "post" || scope == "create" || scope == "update" {
|
||
|
postPresent = true
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
if !postPresent {
|
||
|
return false, errors.New("post is not present in the scope")
|
||
|
}
|
||
|
return true, nil
|
||
|
}
|
||
|
|
||
|
func CheckAuthorization(entry *Entry, token string) bool {
|
||
|
if len(token) < 1 { // there is no token provided
|
||
|
return false
|
||
|
} else {
|
||
|
entry.token = token
|
||
|
}
|
||
|
if ok, err := checkAccess(entry.token); ok {
|
||
|
return true
|
||
|
} else if err != nil {
|
||
|
return false
|
||
|
} else {
|
||
|
return false
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func GetContentType(contentType string) (ContentType, error) {
|
||
|
if contentType != "" {
|
||
|
if strings.Contains(contentType, "application/x-www-form-urlencoded") {
|
||
|
return WwwForm, nil
|
||
|
}
|
||
|
if strings.Contains(contentType, "application/json") {
|
||
|
return Json, nil
|
||
|
}
|
||
|
if strings.Contains(contentType, "multipart/form-data") {
|
||
|
return Multipart, nil
|
||
|
}
|
||
|
return UnsupportedType, errors.New("content-type " + contentType + " is not supported, use application/x-www-form-urlencoded")
|
||
|
}
|
||
|
return UnsupportedType, errors.New("content-type is not provided in the request")
|
||
|
}
|