mirror of
https://github.com/elyby/chrly.git
synced 2026-04-28 18:36:06 +05:30
Removed amqp worker command implementation
Removed Accounts Ely.by api implementation
This commit is contained in:
@@ -1,166 +0,0 @@
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Addr string
|
||||
Id string
|
||||
Secret string
|
||||
Scopes []string
|
||||
|
||||
Client *http.Client
|
||||
}
|
||||
|
||||
type Token struct {
|
||||
AccessToken string `json:"access_token"`
|
||||
TokenType string `json:"token_type"`
|
||||
ExpiresIn int `json:"expires_in"`
|
||||
config *Config
|
||||
}
|
||||
|
||||
func (config *Config) GetToken() (*Token, error) {
|
||||
form := url.Values{}
|
||||
form.Add("client_id", config.Id)
|
||||
form.Add("client_secret", config.Secret)
|
||||
form.Add("grant_type", "client_credentials")
|
||||
form.Add("scope", strings.Join(config.Scopes, ","))
|
||||
|
||||
response, err := config.getHttpClient().Post(config.getTokenUrl(), "application/x-www-form-urlencoded", strings.NewReader(form.Encode()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
var result *Token
|
||||
responseError := handleResponse(response)
|
||||
if responseError != nil {
|
||||
return nil, responseError
|
||||
}
|
||||
|
||||
body, _ := ioutil.ReadAll(response.Body)
|
||||
unmarshalError := json.Unmarshal(body, &result)
|
||||
if unmarshalError != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result.config = config
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (config *Config) getTokenUrl() string {
|
||||
return concatenateHostAndPath(config.Addr, "/api/oauth2/v1/token")
|
||||
}
|
||||
|
||||
func (config *Config) getHttpClient() *http.Client {
|
||||
if config.Client == nil {
|
||||
config.Client = &http.Client{}
|
||||
}
|
||||
|
||||
return config.Client
|
||||
}
|
||||
|
||||
type AccountInfoResponse struct {
|
||||
Id int `json:"id"`
|
||||
Uuid string `json:"uuid"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
func (token *Token) AccountInfo(attribute string, value string) (*AccountInfoResponse, error) {
|
||||
request := token.newRequest("GET", token.accountInfoUrl(), nil)
|
||||
|
||||
query := request.URL.Query()
|
||||
query.Add(attribute, value)
|
||||
request.URL.RawQuery = query.Encode()
|
||||
|
||||
response, err := token.config.Client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
var info *AccountInfoResponse
|
||||
|
||||
responseError := handleResponse(response)
|
||||
if responseError != nil {
|
||||
return nil, responseError
|
||||
}
|
||||
|
||||
body, _ := ioutil.ReadAll(response.Body)
|
||||
json.Unmarshal(body, &info)
|
||||
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func (token *Token) accountInfoUrl() string {
|
||||
return concatenateHostAndPath(token.config.Addr, "/api/internal/accounts/info")
|
||||
}
|
||||
|
||||
func (token *Token) newRequest(method string, urlStr string, body io.Reader) *http.Request {
|
||||
request, err := http.NewRequest(method, urlStr, body)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
request.Header.Add("Authorization", "Bearer " + token.AccessToken)
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
func concatenateHostAndPath(host string, pathToJoin string) string {
|
||||
u, _ := url.Parse(host)
|
||||
u.Path = path.Join(u.Path, pathToJoin)
|
||||
|
||||
return u.String()
|
||||
}
|
||||
|
||||
type UnauthorizedResponse struct {}
|
||||
|
||||
func (err UnauthorizedResponse) Error() string {
|
||||
return "Unauthorized response"
|
||||
}
|
||||
|
||||
type ForbiddenResponse struct {}
|
||||
|
||||
func (err ForbiddenResponse) Error() string {
|
||||
return "Forbidden response"
|
||||
}
|
||||
|
||||
type NotFoundResponse struct {}
|
||||
|
||||
func (err NotFoundResponse) Error() string {
|
||||
return "Not found"
|
||||
}
|
||||
|
||||
type NotSuccessResponse struct {
|
||||
StatusCode int
|
||||
}
|
||||
|
||||
func (err NotSuccessResponse) Error() string {
|
||||
return fmt.Sprintf("Response code is \"%d\"", err.StatusCode)
|
||||
}
|
||||
|
||||
func handleResponse(response *http.Response) error {
|
||||
switch status := response.StatusCode; status {
|
||||
case 200:
|
||||
return nil
|
||||
case 401:
|
||||
return &UnauthorizedResponse{}
|
||||
case 403:
|
||||
return &ForbiddenResponse{}
|
||||
case 404:
|
||||
return &NotFoundResponse{}
|
||||
default:
|
||||
return &NotSuccessResponse{status}
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
testify "github.com/stretchr/testify/assert"
|
||||
"gopkg.in/h2non/gock.v1"
|
||||
)
|
||||
|
||||
func TestConfig_GetToken(t *testing.T) {
|
||||
assert := testify.New(t)
|
||||
|
||||
defer gock.Off()
|
||||
gock.New("https://account.ely.by").
|
||||
Post("/api/oauth2/v1/token").
|
||||
Body(strings.NewReader("client_id=mock-id&client_secret=mock-secret&grant_type=client_credentials&scope=scope1%2Cscope2")).
|
||||
Reply(200).
|
||||
JSON(map[string]interface{}{
|
||||
"access_token": "mocked-token",
|
||||
"token_type": "Bearer",
|
||||
"expires_in": 86400,
|
||||
})
|
||||
|
||||
client := &http.Client{}
|
||||
gock.InterceptClient(client)
|
||||
|
||||
config := &Config{
|
||||
Addr: "https://account.ely.by",
|
||||
Id: "mock-id",
|
||||
Secret: "mock-secret",
|
||||
Scopes: []string{"scope1", "scope2"},
|
||||
Client: client,
|
||||
}
|
||||
|
||||
result, err := config.GetToken()
|
||||
if assert.NoError(err) {
|
||||
assert.Equal("mocked-token", result.AccessToken)
|
||||
assert.Equal("Bearer", result.TokenType)
|
||||
assert.Equal(86400, result.ExpiresIn)
|
||||
}
|
||||
}
|
||||
|
||||
func TestToken_AccountInfo(t *testing.T) {
|
||||
assert := testify.New(t)
|
||||
|
||||
defer gock.Off()
|
||||
// To test valid behavior
|
||||
gock.New("https://account.ely.by").
|
||||
Get("/api/internal/accounts/info").
|
||||
MatchParam("id", "1").
|
||||
MatchHeader("Authorization", "Bearer mock-token").
|
||||
Reply(200).
|
||||
JSON(map[string]interface{}{
|
||||
"id": 1,
|
||||
"uuid": "0f657aa8-bfbe-415d-b700-5750090d3af3",
|
||||
"username": "dummy",
|
||||
"email": "dummy@ely.by",
|
||||
})
|
||||
|
||||
// To test behavior on invalid or expired token
|
||||
gock.New("https://account.ely.by").
|
||||
Get("/api/internal/accounts/info").
|
||||
MatchParam("id", "1").
|
||||
MatchHeader("Authorization", "Bearer mock-token").
|
||||
Reply(401).
|
||||
JSON(map[string]interface{}{
|
||||
"name": "Unauthorized",
|
||||
"message": "Incorrect token",
|
||||
"code": 0,
|
||||
"status": 401,
|
||||
})
|
||||
|
||||
client := &http.Client{}
|
||||
gock.InterceptClient(client)
|
||||
|
||||
token := &Token{
|
||||
AccessToken: "mock-token",
|
||||
config: &Config{
|
||||
Addr: "https://account.ely.by",
|
||||
Client: client,
|
||||
},
|
||||
}
|
||||
|
||||
result, err := token.AccountInfo("id", "1")
|
||||
if assert.NoError(err) {
|
||||
assert.Equal(1, result.Id)
|
||||
assert.Equal("0f657aa8-bfbe-415d-b700-5750090d3af3", result.Uuid)
|
||||
assert.Equal("dummy", result.Username)
|
||||
assert.Equal("dummy@ely.by", result.Email)
|
||||
}
|
||||
|
||||
result2, err2 := token.AccountInfo("id", "1")
|
||||
assert.Nil(result2)
|
||||
assert.Error(err2)
|
||||
assert.IsType(&UnauthorizedResponse{}, err2)
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
package accounts
|
||||
|
||||
type AutoRefresh struct {
|
||||
token *Token
|
||||
config *Config
|
||||
repeatsCount int
|
||||
}
|
||||
|
||||
const repeatsLimit = 3
|
||||
|
||||
func (config *Config) GetTokenWithAutoRefresh() *AutoRefresh {
|
||||
return &AutoRefresh{
|
||||
config: config,
|
||||
}
|
||||
}
|
||||
|
||||
func (refresher *AutoRefresh) AccountInfo(attribute string, value string) (*AccountInfoResponse, error) {
|
||||
defer refresher.resetRepeatsCount()
|
||||
|
||||
apiToken, err := refresher.getToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result, err := apiToken.AccountInfo(attribute, value)
|
||||
if err != nil {
|
||||
_, isTokenExpire := err.(*UnauthorizedResponse)
|
||||
if !isTokenExpire || refresher.repeatsCount >= repeatsLimit - 1 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
refresher.repeatsCount++
|
||||
refresher.token = nil
|
||||
|
||||
return refresher.AccountInfo(attribute, value)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (refresher *AutoRefresh) getToken() (*Token, error) {
|
||||
if refresher.token == nil {
|
||||
newToken, err := refresher.config.GetToken()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
refresher.token = newToken
|
||||
}
|
||||
|
||||
return refresher.token, nil
|
||||
}
|
||||
|
||||
func (refresher *AutoRefresh) resetRepeatsCount() {
|
||||
refresher.repeatsCount = 0
|
||||
}
|
||||
@@ -1,242 +0,0 @@
|
||||
package accounts
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
testify "github.com/stretchr/testify/assert"
|
||||
"gopkg.in/h2non/gock.v1"
|
||||
)
|
||||
|
||||
var config = &Config{
|
||||
Addr: "https://account.ely.by",
|
||||
Id: "mock-id",
|
||||
Secret: "mock-secret",
|
||||
Scopes: []string{"scope1", "scope2"},
|
||||
}
|
||||
|
||||
func TestConfig_GetTokenWithAutoRefresh(t *testing.T) {
|
||||
assert := testify.New(t)
|
||||
|
||||
testConfig := &Config{}
|
||||
*testConfig = *config
|
||||
|
||||
result := testConfig.GetTokenWithAutoRefresh()
|
||||
assert.Equal(testConfig, result.config)
|
||||
}
|
||||
|
||||
func TestAutoRefresh_AccountInfo(t *testing.T) {
|
||||
assert := testify.New(t)
|
||||
|
||||
defer gock.Off()
|
||||
gock.New("https://account.ely.by").
|
||||
Post("/api/oauth2/v1/token").
|
||||
Body(strings.NewReader("client_id=mock-id&client_secret=mock-secret&grant_type=client_credentials&scope=scope1%2Cscope2")).
|
||||
Reply(200).
|
||||
JSON(map[string]interface{}{
|
||||
"access_token": "mocked-token",
|
||||
"token_type": "Bearer",
|
||||
"expires_in": 86400,
|
||||
})
|
||||
|
||||
gock.New("https://account.ely.by").
|
||||
Get("/api/internal/accounts/info").
|
||||
Times(2).
|
||||
MatchParam("id", "1").
|
||||
MatchHeader("Authorization", "Bearer mocked-token").
|
||||
Reply(200).
|
||||
JSON(map[string]interface{}{
|
||||
"id": 1,
|
||||
"uuid": "0f657aa8-bfbe-415d-b700-5750090d3af3",
|
||||
"username": "dummy",
|
||||
"email": "dummy@ely.by",
|
||||
})
|
||||
|
||||
client := &http.Client{}
|
||||
gock.InterceptClient(client)
|
||||
|
||||
testConfig := &Config{}
|
||||
*testConfig = *config
|
||||
testConfig.Client = client
|
||||
|
||||
autoRefresher := testConfig.GetTokenWithAutoRefresh()
|
||||
result, err := autoRefresher.AccountInfo("id", "1")
|
||||
if assert.NoError(err) {
|
||||
assert.Equal(1, result.Id)
|
||||
assert.Equal("0f657aa8-bfbe-415d-b700-5750090d3af3", result.Uuid)
|
||||
assert.Equal("dummy", result.Username)
|
||||
assert.Equal("dummy@ely.by", result.Email)
|
||||
}
|
||||
|
||||
result2, err2 := autoRefresher.AccountInfo("id", "1")
|
||||
if assert.NoError(err2) {
|
||||
assert.Equal(result, result2, "Results should still be same without token refreshing")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAutoRefresh_AccountInfo2(t *testing.T) {
|
||||
assert := testify.New(t)
|
||||
|
||||
defer gock.Off()
|
||||
gock.New("https://account.ely.by").
|
||||
Post("/api/oauth2/v1/token").
|
||||
Body(strings.NewReader("client_id=mock-id&client_secret=mock-secret&grant_type=client_credentials&scope=scope1%2Cscope2")).
|
||||
Reply(200).
|
||||
JSON(map[string]interface{}{
|
||||
"access_token": "mocked-token-1",
|
||||
"token_type": "Bearer",
|
||||
"expires_in": 86400,
|
||||
})
|
||||
|
||||
gock.New("https://account.ely.by").
|
||||
Get("/api/internal/accounts/info").
|
||||
MatchParam("id", "1").
|
||||
MatchHeader("Authorization", "Bearer mocked-token-1").
|
||||
Reply(200).
|
||||
JSON(map[string]interface{}{
|
||||
"id": 1,
|
||||
"uuid": "0f657aa8-bfbe-415d-b700-5750090d3af3",
|
||||
"username": "dummy",
|
||||
"email": "dummy@ely.by",
|
||||
})
|
||||
|
||||
gock.New("https://account.ely.by").
|
||||
Get("/api/internal/accounts/info").
|
||||
MatchParam("id", "1").
|
||||
MatchHeader("Authorization", "Bearer mocked-token-1").
|
||||
Reply(401).
|
||||
JSON(map[string]interface{}{
|
||||
"name": "Unauthorized",
|
||||
"message": "Incorrect token",
|
||||
"code": 0,
|
||||
"status": 401,
|
||||
})
|
||||
|
||||
gock.New("https://account.ely.by").
|
||||
Post("/api/oauth2/v1/token").
|
||||
Body(strings.NewReader("client_id=mock-id&client_secret=mock-secret&grant_type=client_credentials&scope=scope1%2Cscope2")).
|
||||
Reply(200).
|
||||
JSON(map[string]interface{}{
|
||||
"access_token": "mocked-token-2",
|
||||
"token_type": "Bearer",
|
||||
"expires_in": 86400,
|
||||
})
|
||||
|
||||
gock.New("https://account.ely.by").
|
||||
Get("/api/internal/accounts/info").
|
||||
MatchParam("id", "1").
|
||||
MatchHeader("Authorization", "Bearer mocked-token-2").
|
||||
Reply(200).
|
||||
JSON(map[string]interface{}{
|
||||
"id": 1,
|
||||
"uuid": "0f657aa8-bfbe-415d-b700-5750090d3af3",
|
||||
"username": "dummy",
|
||||
"email": "dummy@ely.by",
|
||||
})
|
||||
|
||||
client := &http.Client{}
|
||||
gock.InterceptClient(client)
|
||||
|
||||
testConfig := &Config{}
|
||||
*testConfig = *config
|
||||
testConfig.Client = client
|
||||
|
||||
autoRefresher := testConfig.GetTokenWithAutoRefresh()
|
||||
result, err := autoRefresher.AccountInfo("id", "1")
|
||||
if assert.NoError(err) {
|
||||
assert.Equal(1, result.Id)
|
||||
assert.Equal("0f657aa8-bfbe-415d-b700-5750090d3af3", result.Uuid)
|
||||
assert.Equal("dummy", result.Username)
|
||||
assert.Equal("dummy@ely.by", result.Email)
|
||||
}
|
||||
|
||||
result2, err2 := autoRefresher.AccountInfo("id", "1")
|
||||
if assert.NoError(err2) {
|
||||
assert.Equal(result, result2, "Results should still be same with refreshed token")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAutoRefresh_AccountInfo3(t *testing.T) {
|
||||
assert := testify.New(t)
|
||||
|
||||
defer gock.Off()
|
||||
gock.New("https://account.ely.by").
|
||||
Post("/api/oauth2/v1/token").
|
||||
Body(strings.NewReader("client_id=mock-id&client_secret=mock-secret&grant_type=client_credentials&scope=scope1%2Cscope2")).
|
||||
Reply(200).
|
||||
JSON(map[string]interface{}{
|
||||
"access_token": "mocked-token-1",
|
||||
"token_type": "Bearer",
|
||||
"expires_in": 86400,
|
||||
})
|
||||
|
||||
gock.New("https://account.ely.by").
|
||||
Get("/api/internal/accounts/info").
|
||||
MatchParam("id", "1").
|
||||
MatchHeader("Authorization", "Bearer mocked-token-1").
|
||||
Reply(404).
|
||||
JSON(map[string]interface{}{
|
||||
"name": "Not Found",
|
||||
"message": "Page not found.",
|
||||
"code": 0,
|
||||
"status": 404,
|
||||
})
|
||||
|
||||
client := &http.Client{}
|
||||
gock.InterceptClient(client)
|
||||
|
||||
testConfig := &Config{}
|
||||
*testConfig = *config
|
||||
testConfig.Client = client
|
||||
|
||||
autoRefresher := testConfig.GetTokenWithAutoRefresh()
|
||||
result, err := autoRefresher.AccountInfo("id", "1")
|
||||
assert.Nil(result)
|
||||
assert.Error(err)
|
||||
assert.IsType(&NotFoundResponse{}, err)
|
||||
}
|
||||
|
||||
func TestAutoRefresh_AccountInfo4(t *testing.T) {
|
||||
assert := testify.New(t)
|
||||
|
||||
defer gock.Off()
|
||||
gock.New("https://account.ely.by").
|
||||
Post("/api/oauth2/v1/token").
|
||||
Times(3).
|
||||
Body(strings.NewReader("client_id=mock-id&client_secret=mock-secret&grant_type=client_credentials&scope=scope1%2Cscope2")).
|
||||
Reply(200).
|
||||
JSON(map[string]interface{}{
|
||||
"access_token": "mocked-token-1",
|
||||
"token_type": "Bearer",
|
||||
"expires_in": 86400,
|
||||
})
|
||||
|
||||
gock.New("https://account.ely.by").
|
||||
Get("/api/internal/accounts/info").
|
||||
Times(3).
|
||||
MatchParam("id", "1").
|
||||
MatchHeader("Authorization", "Bearer mocked-token-1").
|
||||
Reply(401).
|
||||
JSON(map[string]interface{}{
|
||||
"name": "Unauthorized",
|
||||
"message": "Incorrect token",
|
||||
"code": 0,
|
||||
"status": 401,
|
||||
})
|
||||
|
||||
client := &http.Client{}
|
||||
gock.InterceptClient(client)
|
||||
|
||||
testConfig := &Config{}
|
||||
*testConfig = *config
|
||||
testConfig.Client = client
|
||||
|
||||
autoRefresher := testConfig.GetTokenWithAutoRefresh()
|
||||
result, err := autoRefresher.AccountInfo("id", "1")
|
||||
assert.Nil(result)
|
||||
assert.Error(err)
|
||||
if !assert.IsType(&UnauthorizedResponse{}, err) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user