Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Интерфейс для авторизации #88

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 13 additions & 6 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ type VK struct {
Version string
Client *http.Client
Limit int
Auth Authenticator
Handler func(method string, params Params) (Response, error)

mux sync.Mutex
Expand Down Expand Up @@ -125,6 +126,7 @@ type Response struct {
func Init(token string) *VK {
var vk VK
vk.AccessToken = token
vk.Auth = TokenAuthenticator(token)
vk.Version = Version

vk.Handler = vk.defaultHandler
Expand Down Expand Up @@ -211,8 +213,9 @@ func (vk *VK) defaultHandler(method string, params Params) (response Response, e
//
// TODO: remove in v2
func (vk *VK) Request(method string, params Params) ([]byte, error) {
if _, ok := params["access_token"]; !ok {
params["access_token"] = vk.AccessToken
err := vk.Auth.Authenticate(params)
if err != nil {
return nil, err
}

if _, ok := params["v"]; !ok {
Expand All @@ -238,12 +241,16 @@ func (vk *VK) RequestUnmarshal(method string, params Params, obj interface{}) er
//
// https://vk.com/dev/Execute
func (vk *VK) Execute(code string, obj interface{}) error {
params := Params{
"code": code,
"access_token": vk.AccessToken,
"v": vk.Version,
params := Params{}

err := vk.Auth.Authenticate(params)
if err != nil {
return err
}

params["v"] = vk.Version
params["code"] = code

resp, err := vk.Handler("execute", params)

// Add execute errors
Expand Down
102 changes: 102 additions & 0 deletions api/authenticator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package api

import (
"bytes"
"encoding/json"
"net/http"

"github.com/SevereCloud/vksdk/api/errors"
)

// Authenticator interface
type Authenticator interface {
SevereCloud marked this conversation as resolved.
Show resolved Hide resolved
Authenticate(params Params) error
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Возможно, стоит использовать req *http.Request вместо params Params
Тогда, например, можно будет установить конкретные куки(получение токена с Desktop в vk_api)

}

// AuthenticatorFunc func
type AuthenticatorFunc func(params Params) error
SevereCloud marked this conversation as resolved.
Show resolved Hide resolved

// Authenticate method
// Implements Authenticator for AuthenticatorFunc
func (f AuthenticatorFunc) Authenticate(params Params) error {
SevereCloud marked this conversation as resolved.
Show resolved Hide resolved
return f(params)
}

// TokenAuthenticator func
// Creates new Authenticator which sets given access_token
func TokenAuthenticator(token string) Authenticator {
return AuthenticatorFunc(func(params Params) error {
if _, ok := params["access_token"]; !ok {
params["access_token"] = token
}

return nil
})
}

// AuthCodeFlowRequest struct
type AuthCodeFlowRequest struct {
ClientID int `json:"client_id"`
ClientSecret string `json:"client_secret"`
RedirectURL string `json:"redirect_url"`
Code string `json:"code"`
Version string `json:"v"`
}

// TokenResponse struct
type TokenResponse struct {
AccessToken string `json:"access_token"`
ExpiresIn int `json:"expires_in"`
UserID int `json:"user_id"`
}

// gets token from given AuthCodeFlowRequest
func authCodeFlow(auth AuthCodeFlowRequest) (token TokenResponse, err error) {
encoded, err := json.Marshal(auth)
if err != nil {
return
}

resp, err := http.Post(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

response body must be closed (from bodyclose)

"https://oauth.vk.com/access_token",
"application/json",
bytes.NewReader(encoded),
)
if err != nil {
return
}

if resp.Body != nil {
defer resp.Body.Close()
}

var response Response

err = json.NewDecoder(resp.Body).Decode(&response)
if err != nil {
SevereCloud marked this conversation as resolved.
Show resolved Hide resolved
return
}

err = errors.New(response.Error)
if err != nil {
return
}

err = json.Unmarshal(response.Response, &token)

return token, err
}

// CodeAuthenticator func
// Authorization code flow implementation
func CodeAuthenticator(auth AuthCodeFlowRequest) (Authenticator, error) {
r, err := authCodeFlow(auth)

return AuthenticatorFunc(func(params Params) error {
SevereCloud marked this conversation as resolved.
Show resolved Hide resolved
if _, ok := params["access_token"]; !ok {
params["access_token"] = r.AccessToken
}

return nil
}), err
}