75 lines
1.9 KiB
Go
75 lines
1.9 KiB
Go
|
package login
|
||
|
|
||
|
import (
|
||
|
"crypto/hmac"
|
||
|
"crypto/sha256"
|
||
|
"encoding/hex"
|
||
|
|
||
|
http "github.com/valyala/fasthttp"
|
||
|
)
|
||
|
|
||
|
type (
|
||
|
Widget struct {
|
||
|
accessToken string
|
||
|
}
|
||
|
|
||
|
// User contains data about authenticated user.
|
||
|
User struct {
|
||
|
ID int `json:"id"`
|
||
|
AuthDate int64 `json:"auth_date"`
|
||
|
FirstName string `json:"first_name"`
|
||
|
Hash string `json:"hash"`
|
||
|
LastName string `json:"last_name,omitempty"`
|
||
|
PhotoURL string `json:"photo_url,omitempty"`
|
||
|
Username string `json:"username,omitempty"`
|
||
|
}
|
||
|
)
|
||
|
|
||
|
// Key represents available and supported query arguments keys.
|
||
|
const (
|
||
|
KeyAuthDate = "auth_date"
|
||
|
KeyFirstName = "first_name"
|
||
|
KeyHash = "hash"
|
||
|
KeyID = "id"
|
||
|
KeyLastName = "last_name"
|
||
|
KeyPhotoURL = "photo_url"
|
||
|
KeyUsername = "username"
|
||
|
)
|
||
|
|
||
|
func NewWidget(accessToken string) *Widget {
|
||
|
return &Widget{accessToken: accessToken}
|
||
|
}
|
||
|
|
||
|
// CheckAuthorization verify the authentication and the integrity of the data
|
||
|
// received by comparing the received hash parameter with the hexadecimal
|
||
|
// representation of the HMAC-SHA-256 signature of the data-check-string with the
|
||
|
// SHA256 hash of the bot's token used as a secret key.
|
||
|
func (w *Widget) CheckAuthorization(u User) (bool, error) {
|
||
|
hash, err := w.GenerateHash(u)
|
||
|
return hash == u.Hash, err
|
||
|
}
|
||
|
|
||
|
func (w *Widget) GenerateHash(u User) (string, error) {
|
||
|
a := http.AcquireArgs()
|
||
|
defer http.ReleaseArgs(a)
|
||
|
|
||
|
// WARN: do not change order of this args, it must be alphabetical
|
||
|
a.SetUint(KeyAuthDate, int(u.AuthDate))
|
||
|
a.Set(KeyFirstName, u.FirstName)
|
||
|
a.SetUint(KeyID, u.ID)
|
||
|
if u.LastName != "" {
|
||
|
a.Set(KeyLastName, u.LastName)
|
||
|
}
|
||
|
if u.PhotoURL != "" {
|
||
|
a.Set(KeyPhotoURL, u.PhotoURL)
|
||
|
}
|
||
|
if u.Username != "" {
|
||
|
a.Set(KeyUsername, u.Username)
|
||
|
}
|
||
|
|
||
|
secretKey := sha256.Sum256([]byte(w.accessToken))
|
||
|
h := hmac.New(sha256.New, secretKey[0:])
|
||
|
_, err := h.Write(a.QueryString())
|
||
|
return hex.EncodeToString(h.Sum(nil)), err
|
||
|
}
|