Add token api (app and client)
This commit is contained in:
parent
fadf989158
commit
8dfb5c7a69
|
|
@ -0,0 +1,130 @@
|
|||
// Code generated by mockery v1.0.0
|
||||
package mock
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
import model "github.com/jmattheis/memo/model"
|
||||
|
||||
// MockTokenDatabase is an autogenerated mock type for the TokenDatabase type
|
||||
type MockTokenDatabase struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// CreateApplication provides a mock function with given fields: application
|
||||
func (_m *MockTokenDatabase) CreateApplication(application *model.Application) error {
|
||||
ret := _m.Called(application)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(*model.Application) error); ok {
|
||||
r0 = rf(application)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// CreateClient provides a mock function with given fields: client
|
||||
func (_m *MockTokenDatabase) CreateClient(client *model.Client) error {
|
||||
ret := _m.Called(client)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(*model.Client) error); ok {
|
||||
r0 = rf(client)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteApplicationByID provides a mock function with given fields: id
|
||||
func (_m *MockTokenDatabase) DeleteApplicationByID(id string) error {
|
||||
ret := _m.Called(id)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||
r0 = rf(id)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteClientID provides a mock function with given fields: id
|
||||
func (_m *MockTokenDatabase) DeleteClientID(id string) error {
|
||||
ret := _m.Called(id)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||
r0 = rf(id)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetApplicationByID provides a mock function with given fields: id
|
||||
func (_m *MockTokenDatabase) GetApplicationByID(id string) *model.Application {
|
||||
ret := _m.Called(id)
|
||||
|
||||
var r0 *model.Application
|
||||
if rf, ok := ret.Get(0).(func(string) *model.Application); ok {
|
||||
r0 = rf(id)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Application)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetApplicationsByUser provides a mock function with given fields: userID
|
||||
func (_m *MockTokenDatabase) GetApplicationsByUser(userID uint) []*model.Application {
|
||||
ret := _m.Called(userID)
|
||||
|
||||
var r0 []*model.Application
|
||||
if rf, ok := ret.Get(0).(func(uint) []*model.Application); ok {
|
||||
r0 = rf(userID)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.Application)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetClientByID provides a mock function with given fields: id
|
||||
func (_m *MockTokenDatabase) GetClientByID(id string) *model.Client {
|
||||
ret := _m.Called(id)
|
||||
|
||||
var r0 *model.Client
|
||||
if rf, ok := ret.Get(0).(func(string) *model.Client); ok {
|
||||
r0 = rf(id)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*model.Client)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// GetClientsByUser provides a mock function with given fields: userID
|
||||
func (_m *MockTokenDatabase) GetClientsByUser(userID uint) []*model.Client {
|
||||
ret := _m.Called(userID)
|
||||
|
||||
var r0 []*model.Client
|
||||
if rf, ok := ret.Get(0).(func(uint) []*model.Client); ok {
|
||||
r0 = rf(userID)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.Client)
|
||||
}
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/jmattheis/memo/auth"
|
||||
"github.com/jmattheis/memo/model"
|
||||
)
|
||||
|
||||
// The TokenDatabase interface for encapsulating database access.
|
||||
type TokenDatabase interface {
|
||||
CreateApplication(application *model.Application) error
|
||||
GetApplicationByID(id string) *model.Application
|
||||
GetApplicationsByUser(userID uint) []*model.Application
|
||||
DeleteApplicationByID(id string) error
|
||||
|
||||
CreateClient(client *model.Client) error
|
||||
GetClientByID(id string) *model.Client
|
||||
GetClientsByUser(userID uint) []*model.Client
|
||||
DeleteClientID(id string) error
|
||||
}
|
||||
|
||||
// The TokenAPI provides handlers for managing clients and applications.
|
||||
type TokenAPI struct {
|
||||
DB TokenDatabase
|
||||
}
|
||||
|
||||
// CreateApplication creates an application and returns the access token.
|
||||
func (a *TokenAPI) CreateApplication(ctx *gin.Context) {
|
||||
app := model.Application{}
|
||||
if err := ctx.Bind(&app); err == nil {
|
||||
app.ID = generateNotExistingToken(auth.GenerateApplicationToken, a.applicationExists)
|
||||
app.UserID = auth.GetUserID(ctx)
|
||||
a.DB.CreateApplication(&app)
|
||||
ctx.JSON(200, app)
|
||||
}
|
||||
}
|
||||
|
||||
// CreateClient creates a client and returns the access token.
|
||||
func (a *TokenAPI) CreateClient(ctx *gin.Context) {
|
||||
client := model.Client{}
|
||||
if err := ctx.Bind(&client); err == nil {
|
||||
client.ID = generateNotExistingToken(auth.GenerateClientToken, a.clientExists)
|
||||
client.UserID = auth.GetUserID(ctx)
|
||||
a.DB.CreateClient(&client)
|
||||
ctx.JSON(200, client)
|
||||
}
|
||||
}
|
||||
|
||||
// GetApplications returns all applications a user has.
|
||||
func (a *TokenAPI) GetApplications(ctx *gin.Context) {
|
||||
userID := auth.GetUserID(ctx)
|
||||
apps := a.DB.GetApplicationsByUser(userID)
|
||||
ctx.JSON(200, apps)
|
||||
}
|
||||
|
||||
// GetClients returns all clients a user has.
|
||||
func (a *TokenAPI) GetClients(ctx *gin.Context) {
|
||||
userID := auth.GetUserID(ctx)
|
||||
apps := a.DB.GetClientsByUser(userID)
|
||||
ctx.JSON(200, apps)
|
||||
}
|
||||
|
||||
// DeleteApplication deletes an application by its id.
|
||||
func (a *TokenAPI) DeleteApplication(ctx *gin.Context) {
|
||||
appID := ctx.Param("id")
|
||||
if app := a.DB.GetApplicationByID(appID); app != nil && app.UserID == auth.GetUserID(ctx) {
|
||||
a.DB.DeleteApplicationByID(appID)
|
||||
} else {
|
||||
ctx.AbortWithError(404, fmt.Errorf("app with id %s doesn't exists", appID))
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteClient deletes a client by its id.
|
||||
func (a *TokenAPI) DeleteClient(ctx *gin.Context) {
|
||||
clientID := ctx.Param("id")
|
||||
if client := a.DB.GetClientByID(clientID); client != nil && client.UserID == auth.GetUserID(ctx) {
|
||||
a.DB.DeleteClientID(clientID)
|
||||
} else {
|
||||
ctx.AbortWithError(404, fmt.Errorf("client with id %s doesn't exists", clientID))
|
||||
}
|
||||
}
|
||||
|
||||
func (a *TokenAPI) applicationExists(appID string) bool {
|
||||
return a.DB.GetApplicationByID(appID) != nil
|
||||
}
|
||||
|
||||
func (a *TokenAPI) clientExists(clientID string) bool {
|
||||
return a.DB.GetClientByID(clientID) != nil
|
||||
}
|
||||
|
||||
func generateNotExistingToken(generateToken func() string, tokenExists func(token string) bool) string {
|
||||
for {
|
||||
token := generateToken()
|
||||
if !tokenExists(token) {
|
||||
return token
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,294 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/gin-gonic/gin"
|
||||
apimock "github.com/jmattheis/memo/api/mock"
|
||||
"github.com/jmattheis/memo/model"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var (
|
||||
firstApplicationToken = "APorrUa5b1IIK3y"
|
||||
secondApplicationToken = "AKo_Pp6ww_9vZal"
|
||||
firstClientToken = "CPorrUa5b1IIK3y"
|
||||
secondClientToken = "CKo_Pp6ww_9vZal"
|
||||
)
|
||||
|
||||
func TestTokenSuite(t *testing.T) {
|
||||
suite.Run(t, new(TokenSuite))
|
||||
}
|
||||
|
||||
type TokenSuite struct {
|
||||
suite.Suite
|
||||
db *apimock.MockTokenDatabase
|
||||
a *TokenAPI
|
||||
ctx *gin.Context
|
||||
recorder *httptest.ResponseRecorder
|
||||
}
|
||||
|
||||
func (s *TokenSuite) BeforeTest(suiteName, testName string) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
rand.Seed(50)
|
||||
s.recorder = httptest.NewRecorder()
|
||||
s.ctx, _ = gin.CreateTestContext(s.recorder)
|
||||
s.db = &apimock.MockTokenDatabase{}
|
||||
s.a = &TokenAPI{DB: s.db}
|
||||
}
|
||||
|
||||
// test application api
|
||||
|
||||
func (s *TokenSuite) Test_CreateApplication_mapAllParameters() {
|
||||
expected := &model.Application{ID: firstApplicationToken, UserID: 5, Name: "custom_name", Description: "description_text"}
|
||||
|
||||
s.ctx.Set("user", &model.User{ID: 5})
|
||||
s.withFormData("name=custom_name&description=description_text")
|
||||
|
||||
s.db.On("GetApplicationByID", firstApplicationToken).Return(nil)
|
||||
s.db.On("CreateApplication", expected).Return(nil)
|
||||
|
||||
s.a.CreateApplication(s.ctx)
|
||||
|
||||
s.db.AssertCalled(s.T(), "CreateApplication", expected)
|
||||
assert.Equal(s.T(), 200, s.recorder.Code)
|
||||
}
|
||||
|
||||
func (s *TokenSuite) Test_CreateApplication_expectBadRequestOnEmptyName() {
|
||||
s.ctx.Set("user", &model.User{ID: 5})
|
||||
s.withFormData("name=&description=description_text")
|
||||
|
||||
s.a.CreateApplication(s.ctx)
|
||||
|
||||
s.db.AssertNotCalled(s.T(), "CreateApplication", mock.Anything)
|
||||
assert.Equal(s.T(), 400, s.recorder.Code)
|
||||
}
|
||||
|
||||
func (s *TokenSuite) Test_DeleteApplication_expectNotFoundOnCurrentUserIsNotOwner() {
|
||||
s.ctx.Set("user", &model.User{ID: 2})
|
||||
s.ctx.Request = httptest.NewRequest("DELETE", "/token/"+firstApplicationToken, nil)
|
||||
s.ctx.Params = gin.Params{{Key: "id", Value: firstApplicationToken}}
|
||||
|
||||
s.db.On("GetApplicationByID", firstApplicationToken).Return(&model.Application{ID: firstApplicationToken, UserID: 5})
|
||||
|
||||
s.a.DeleteApplication(s.ctx)
|
||||
|
||||
s.db.AssertNotCalled(s.T(), "DeleteApplicationByID", mock.Anything)
|
||||
assert.Equal(s.T(), 404, s.recorder.Code)
|
||||
}
|
||||
|
||||
func (s *TokenSuite) Test_CreateApplication_onlyRequiredParameters() {
|
||||
expected := &model.Application{ID: firstApplicationToken, Name: "custom_name", UserID: 5}
|
||||
|
||||
s.ctx.Set("user", &model.User{ID: 5})
|
||||
s.withFormData("name=custom_name")
|
||||
|
||||
s.db.On("GetApplicationByID", firstApplicationToken).Return(nil)
|
||||
s.db.On("CreateApplication", expected).Return(nil)
|
||||
|
||||
s.a.CreateApplication(s.ctx)
|
||||
|
||||
s.db.AssertCalled(s.T(), "CreateApplication", expected)
|
||||
assert.Equal(s.T(), 200, s.recorder.Code)
|
||||
}
|
||||
|
||||
func (s *TokenSuite) Test_CreateApplication_returnsApplicationWithID() {
|
||||
expected := &model.Application{ID: firstApplicationToken, Name: "custom_name", UserID: 5}
|
||||
|
||||
s.ctx.Set("user", &model.User{ID: 5})
|
||||
s.withFormData("name=custom_name")
|
||||
|
||||
s.db.On("GetApplicationByID", firstApplicationToken).Return(nil)
|
||||
s.db.On("CreateApplication", expected).Return(nil)
|
||||
|
||||
s.a.CreateApplication(s.ctx)
|
||||
|
||||
assert.Equal(s.T(), 200, s.recorder.Code)
|
||||
bytes, _ := ioutil.ReadAll(s.recorder.Body)
|
||||
|
||||
assert.Equal(s.T(), `{"ID":"APorrUa5b1IIK3y","name":"custom_name","description":""}`, string(bytes))
|
||||
}
|
||||
|
||||
func (s *TokenSuite) Test_CreateApplication_withExistingToken() {
|
||||
expected := &model.Application{ID: secondApplicationToken, Name: "custom_name", UserID: 5}
|
||||
|
||||
s.ctx.Set("user", &model.User{ID: 5})
|
||||
s.withFormData("name=custom_name")
|
||||
|
||||
s.db.On("GetApplicationByID", firstApplicationToken).Return(&model.Application{ID: firstApplicationToken})
|
||||
s.db.On("GetApplicationByID", secondApplicationToken).Return(nil)
|
||||
s.db.On("CreateApplication", expected).Return(nil)
|
||||
|
||||
s.a.CreateApplication(s.ctx)
|
||||
|
||||
s.db.AssertCalled(s.T(), "CreateApplication", expected)
|
||||
assert.Equal(s.T(), 200, s.recorder.Code)
|
||||
}
|
||||
|
||||
func (s *TokenSuite) Test_GetApplications() {
|
||||
s.ctx.Set("user", &model.User{ID: 5})
|
||||
s.ctx.Request = httptest.NewRequest("GET", "/tokens", nil)
|
||||
|
||||
s.db.On("GetApplicationsByUser", uint(5)).Return([]*model.Application{
|
||||
{ID: "perfper", Name: "first", Description: "desc"},
|
||||
{ID: "asdasd", Name: "second", Description: "desc2"},
|
||||
})
|
||||
s.a.GetApplications(s.ctx)
|
||||
|
||||
assert.Equal(s.T(), 200, s.recorder.Code)
|
||||
bytes, _ := ioutil.ReadAll(s.recorder.Body)
|
||||
|
||||
assert.Equal(s.T(), `[{"ID":"perfper","name":"first","description":"desc"},{"ID":"asdasd","name":"second","description":"desc2"}]`, string(bytes))
|
||||
}
|
||||
|
||||
func (s *TokenSuite) Test_DeleteApplication_expectNotFound() {
|
||||
s.ctx.Set("user", &model.User{ID: 5})
|
||||
s.ctx.Request = httptest.NewRequest("DELETE", "/token/"+firstApplicationToken, nil)
|
||||
s.ctx.Params = gin.Params{{Key: "id", Value: firstApplicationToken}}
|
||||
|
||||
s.db.On("DeleteApplicationByID", firstApplicationToken).Return(errors.New("what? that does not exist"))
|
||||
s.db.On("GetApplicationByID", firstApplicationToken).Return(nil)
|
||||
|
||||
s.a.DeleteApplication(s.ctx)
|
||||
|
||||
assert.Equal(s.T(), 404, s.recorder.Code)
|
||||
}
|
||||
|
||||
func (s *TokenSuite) Test_DeleteApplication() {
|
||||
s.ctx.Set("user", &model.User{ID: 5})
|
||||
s.ctx.Request = httptest.NewRequest("DELETE", "/token/"+firstApplicationToken, nil)
|
||||
s.ctx.Params = gin.Params{{Key: "id", Value: firstApplicationToken}}
|
||||
|
||||
s.db.On("DeleteApplicationByID", firstApplicationToken).Return(nil)
|
||||
s.db.On("GetApplicationByID", firstApplicationToken).Return(&model.Application{ID: firstApplicationToken, Name: "custom_name", UserID: 5})
|
||||
|
||||
s.a.DeleteApplication(s.ctx)
|
||||
|
||||
assert.Equal(s.T(), 200, s.recorder.Code)
|
||||
}
|
||||
|
||||
// test client api
|
||||
|
||||
func (s *TokenSuite) Test_CreateClient_mapAllParameters() {
|
||||
expected := &model.Client{ID: firstClientToken, UserID: 5, Name: "custom_name"}
|
||||
|
||||
s.ctx.Set("user", &model.User{ID: 5})
|
||||
s.withFormData("name=custom_name&description=description_text")
|
||||
|
||||
s.db.On("GetClientByID", firstClientToken).Return(nil)
|
||||
s.db.On("CreateClient", expected).Return(nil)
|
||||
|
||||
s.a.CreateClient(s.ctx)
|
||||
|
||||
s.db.AssertCalled(s.T(), "CreateClient", expected)
|
||||
assert.Equal(s.T(), 200, s.recorder.Code)
|
||||
}
|
||||
|
||||
func (s *TokenSuite) Test_CreateClient_expectBadRequestOnEmptyName() {
|
||||
s.ctx.Set("user", &model.User{ID: 5})
|
||||
s.withFormData("name=&description=description_text")
|
||||
|
||||
s.a.CreateClient(s.ctx)
|
||||
|
||||
s.db.AssertNotCalled(s.T(), "CreateClient", mock.Anything)
|
||||
assert.Equal(s.T(), 400, s.recorder.Code)
|
||||
}
|
||||
|
||||
func (s *TokenSuite) Test_DeleteClient_expectNotFoundOnCurrentUserIsNotOwner() {
|
||||
s.ctx.Set("user", &model.User{ID: 2})
|
||||
s.ctx.Request = httptest.NewRequest("DELETE", "/token/"+firstClientToken, nil)
|
||||
s.ctx.Params = gin.Params{{Key: "id", Value: firstClientToken}}
|
||||
|
||||
s.db.On("GetClientByID", firstClientToken).Return(&model.Client{ID: firstClientToken, UserID: 5})
|
||||
|
||||
s.a.DeleteClient(s.ctx)
|
||||
|
||||
s.db.AssertNotCalled(s.T(), "DeleteClientID", mock.Anything)
|
||||
assert.Equal(s.T(), 404, s.recorder.Code)
|
||||
}
|
||||
|
||||
func (s *TokenSuite) Test_CreateClient_returnsClientWithID() {
|
||||
expected := &model.Client{ID: firstClientToken, Name: "custom_name", UserID: 5}
|
||||
|
||||
s.ctx.Set("user", &model.User{ID: 5})
|
||||
s.withFormData("name=custom_name")
|
||||
|
||||
s.db.On("GetClientByID", firstClientToken).Return(nil)
|
||||
s.db.On("CreateClient", expected).Return(nil)
|
||||
|
||||
s.a.CreateClient(s.ctx)
|
||||
|
||||
assert.Equal(s.T(), 200, s.recorder.Code)
|
||||
bytes, _ := ioutil.ReadAll(s.recorder.Body)
|
||||
|
||||
assert.Equal(s.T(), `{"ID":"CPorrUa5b1IIK3y","name":"custom_name"}`, string(bytes))
|
||||
}
|
||||
|
||||
func (s *TokenSuite) Test_CreateClient_withExistingToken() {
|
||||
expected := &model.Client{ID: secondClientToken, Name: "custom_name", UserID: 5}
|
||||
|
||||
s.ctx.Set("user", &model.User{ID: 5})
|
||||
s.withFormData("name=custom_name")
|
||||
|
||||
s.db.On("GetClientByID", firstClientToken).Return(&model.Client{ID: firstClientToken})
|
||||
s.db.On("GetClientByID", secondClientToken).Return(nil)
|
||||
s.db.On("CreateClient", expected).Return(nil)
|
||||
|
||||
s.a.CreateClient(s.ctx)
|
||||
|
||||
s.db.AssertCalled(s.T(), "CreateClient", expected)
|
||||
assert.Equal(s.T(), 200, s.recorder.Code)
|
||||
}
|
||||
|
||||
func (s *TokenSuite) Test_GetClients() {
|
||||
s.ctx.Set("user", &model.User{ID: 5})
|
||||
s.ctx.Request = httptest.NewRequest("GET", "/tokens", nil)
|
||||
|
||||
s.db.On("GetClientsByUser", uint(5)).Return([]*model.Client{
|
||||
{ID: "perfper", Name: "first"},
|
||||
{ID: "asdasd", Name: "second"},
|
||||
})
|
||||
s.a.GetClients(s.ctx)
|
||||
|
||||
assert.Equal(s.T(), 200, s.recorder.Code)
|
||||
bytes, _ := ioutil.ReadAll(s.recorder.Body)
|
||||
|
||||
assert.Equal(s.T(), `[{"ID":"perfper","name":"first"},{"ID":"asdasd","name":"second"}]`, string(bytes))
|
||||
}
|
||||
|
||||
func (s *TokenSuite) Test_DeleteClient_expectNotFound() {
|
||||
s.ctx.Set("user", &model.User{ID: 5})
|
||||
s.ctx.Request = httptest.NewRequest("DELETE", "/token/"+firstClientToken, nil)
|
||||
s.ctx.Params = gin.Params{{Key: "id", Value: firstClientToken}}
|
||||
|
||||
s.db.On("DeleteClientID", firstClientToken).Return(errors.New("what? that does not exist"))
|
||||
s.db.On("GetClientByID", firstClientToken).Return(nil)
|
||||
|
||||
s.a.DeleteClient(s.ctx)
|
||||
|
||||
assert.Equal(s.T(), 404, s.recorder.Code)
|
||||
}
|
||||
|
||||
func (s *TokenSuite) Test_DeleteClient() {
|
||||
s.ctx.Set("user", &model.User{ID: 5})
|
||||
s.ctx.Request = httptest.NewRequest("DELETE", "/token/"+firstClientToken, nil)
|
||||
s.ctx.Params = gin.Params{{Key: "id", Value: firstClientToken}}
|
||||
|
||||
s.db.On("DeleteClientID", firstClientToken).Return(nil)
|
||||
s.db.On("GetClientByID", firstClientToken).Return(&model.Client{ID: firstClientToken, Name: "custom_name", UserID: 5})
|
||||
|
||||
s.a.DeleteClient(s.ctx)
|
||||
|
||||
assert.Equal(s.T(), 200, s.recorder.Code)
|
||||
}
|
||||
|
||||
func (s *TokenSuite) withFormData(formData string) {
|
||||
s.ctx.Request = httptest.NewRequest("POST", "/token", strings.NewReader(formData))
|
||||
s.ctx.Request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
var (
|
||||
tokenCharacters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_")
|
||||
randomTokenLength = 14
|
||||
applicationPrefix = "A"
|
||||
clientPrefix = "C"
|
||||
)
|
||||
|
||||
// GenerateApplicationToken generates an application token.
|
||||
func GenerateApplicationToken() string {
|
||||
return generateRandomToken(applicationPrefix)
|
||||
}
|
||||
|
||||
// GenerateClientToken generates a client token.
|
||||
func GenerateClientToken() string {
|
||||
return generateRandomToken(clientPrefix)
|
||||
}
|
||||
|
||||
func generateRandomToken(prefix string) string {
|
||||
b := make([]rune, randomTokenLength)
|
||||
for i := range b {
|
||||
b[i] = tokenCharacters[rand.Intn(len(tokenCharacters))]
|
||||
}
|
||||
return prefix + string(b)
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTokenHavePrefix(t *testing.T) {
|
||||
for i := 0; i < 50; i++ {
|
||||
assert.True(t, strings.HasPrefix(GenerateApplicationToken(), "A"))
|
||||
assert.True(t, strings.HasPrefix(GenerateClientToken(), "C"))
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue