🚨 Removed linter warnings for token

This commit is contained in:
Maxim Lebedev 2021-09-23 23:27:59 +05:00
parent bb1d908c9a
commit a8bc4587ed
Signed by: toby3d
GPG Key ID: 1F14E25B7C119FC5
8 changed files with 102 additions and 40 deletions

View File

@ -7,7 +7,7 @@ import (
"github.com/fasthttp/router"
json "github.com/goccy/go-json"
http "github.com/valyala/fasthttp"
"golang.org/x/xerrors"
"source.toby3d.me/website/oauth/internal/common"
"source.toby3d.me/website/oauth/internal/model"
"source.toby3d.me/website/oauth/internal/token"
@ -23,10 +23,11 @@ type (
Token string
}
//nolint: tagliatelle
VerificationResponse struct {
Me string `json:"me"`
ClientID string `json:"client_id"`
Scope string `json:"scope"`
Me model.URL `json:"me"`
ClientID model.URL `json:"client_id"`
Scope string `json:"scope"`
}
RevocationResponse struct{}
@ -58,7 +59,10 @@ func (h *RequestHandler) Read(ctx *http.RequestCtx) {
token, err := h.useCase.Verify(ctx, string(bytes.TrimSpace(bytes.TrimPrefix(rawToken, []byte("Bearer")))))
if err != nil {
ctx.SetStatusCode(http.StatusBadRequest)
encoder.Encode(err)
if err = encoder.Encode(err); err != nil {
ctx.Error(err.Error(), http.StatusInternalServerError)
}
return
}
@ -75,13 +79,15 @@ func (h *RequestHandler) Read(ctx *http.RequestCtx) {
Scope: strings.Join(token.Scopes, " "),
}); err != nil {
ctx.SetStatusCode(http.StatusInternalServerError)
encoder.Encode(err)
if err = encoder.Encode(err); err != nil {
ctx.Error(err.Error(), http.StatusInternalServerError)
}
}
}
func (h *RequestHandler) Update(ctx *http.RequestCtx) {
switch string(ctx.FormValue(Action)) {
case ActionRevoke:
if strings.EqualFold(string(ctx.FormValue(Action)), ActionRevoke) {
h.Revocation(ctx)
}
}
@ -95,38 +101,49 @@ func (h *RequestHandler) Revocation(ctx *http.RequestCtx) {
req := new(RevocationRequest)
if err := req.bind(ctx); err != nil {
ctx.SetStatusCode(http.StatusBadRequest)
encoder.Encode(err)
if err = encoder.Encode(err); err != nil {
ctx.Error(err.Error(), http.StatusInternalServerError)
}
return
}
if err := h.useCase.Revoke(ctx, req.Token); err != nil {
ctx.SetStatusCode(http.StatusBadRequest)
encoder.Encode(err)
if err = encoder.Encode(err); err != nil {
ctx.Error(err.Error(), http.StatusInternalServerError)
}
return
}
if err := encoder.Encode(&RevocationResponse{}); err != nil {
ctx.SetStatusCode(http.StatusInternalServerError)
encoder.Encode(err)
if err = encoder.Encode(err); err != nil {
ctx.Error(err.Error(), http.StatusInternalServerError)
}
}
}
func (r *RevocationRequest) bind(ctx *http.RequestCtx) error {
if r.Action = string(ctx.FormValue(Action)); !strings.EqualFold(r.Action, ActionRevoke) {
return model.Error{
Code: model.ErrInvalidRequest,
Code: "invalid_request",
Description: "request MUST contain 'action' key with value 'revoke'",
URI: "https://indieauth.spec.indieweb.org/#token-revocation-request",
Frame: xerrors.Caller(1),
}
}
if r.Token = string(ctx.FormValue("token")); r.Token == "" {
return model.Error{
Code: model.ErrInvalidRequest,
Code: "invalid_request",
Description: "request MUST contain the 'token' key with the valid access token as its value",
URI: "https://indieauth.spec.indieweb.org/#token-revocation-request",
Frame: xerrors.Caller(1),
}
}

View File

@ -11,7 +11,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
http "github.com/valyala/fasthttp"
"source.toby3d.me/website/oauth/internal/common"
"source.toby3d.me/website/oauth/internal/model"
delivery "source.toby3d.me/website/oauth/internal/token/delivery/http"
@ -33,6 +32,7 @@ func TestVerification(t *testing.T) {
ClientID: "https://app.example.com/",
Me: "https://user.example.net/",
Scopes: []string{"create", "update", "delete"},
Profile: nil,
}
require.NoError(repo.Create(context.TODO(), &accessToken))
@ -75,6 +75,7 @@ func TestRevocation(t *testing.T) {
ClientID: "https://app.example.com/",
Me: "https://user.example.net/",
Scopes: []string{"create", "update", "delete"},
Profile: nil,
}))
req := http.AcquireRequest()

View File

@ -4,7 +4,6 @@ import (
"context"
"golang.org/x/xerrors"
"source.toby3d.me/website/oauth/internal/model"
)
@ -18,5 +17,6 @@ type Repository interface {
var ErrExist error = model.Error{
Code: "invalid_request",
Description: "this token is already exists",
URI: "",
Frame: xerrors.Caller(1),
}

View File

@ -6,18 +6,16 @@ import (
json "github.com/goccy/go-json"
"github.com/pkg/errors"
"go.etcd.io/bbolt"
bolt "go.etcd.io/bbolt"
"golang.org/x/xerrors"
"source.toby3d.me/website/oauth/internal/model"
"source.toby3d.me/website/oauth/internal/token"
)
type (
Token struct {
AccessToken string `json:"access_token"`
ClientID string `json:"client_id"`
AccessToken string `json:"accessToken"`
ClientID string `json:"clientId"`
Me string `json:"me"`
Scope string `json:"scope"`
Type string `json:"type"`
@ -31,12 +29,13 @@ type (
var ErrNotExist error = xerrors.New("key not exist")
func NewBoltTokenRepository(db *bolt.DB) (token.Repository, error) {
if err := db.Update(func(tx *bbolt.Tx) error {
if err := db.Update(func(tx *bolt.Tx) error {
//nolint: exhaustivestruct
_, err := tx.CreateBucketIfNotExists(Token{}.Bucket())
return err
return errors.Wrap(err, "failed to create a bucket")
}); err != nil {
return nil, err
return nil, errors.Wrap(err, "failed to update the storage structure")
}
return &boltTokenRepository{
@ -46,18 +45,19 @@ func NewBoltTokenRepository(db *bolt.DB) (token.Repository, error) {
func (repo *boltTokenRepository) Get(ctx context.Context, accessToken string) (*model.Token, error) {
result := model.NewToken()
err := repo.db.View(func(tx *bolt.Tx) error {
if err := repo.db.View(func(tx *bolt.Tx) error {
//nolint: exhaustivestruct
if src := tx.Bucket(Token{}.Bucket()).Get([]byte(accessToken)); src != nil {
return NewToken().Bind(src, result)
}
return ErrNotExist
})
if err != nil && !xerrors.Is(err, ErrNotExist) {
return nil, err
}
}); err != nil {
if !xerrors.Is(err, ErrNotExist) {
return nil, errors.Wrap(err, "failed to retrieve token from storage")
}
if xerrors.Is(err, ErrNotExist) {
return nil, nil
}
@ -86,15 +86,32 @@ func (repo *boltTokenRepository) Update(ctx context.Context, accessToken *model.
return errors.Wrap(err, "failed to marshal token")
}
return repo.db.Update(func(tx *bolt.Tx) error {
return tx.Bucket(dto.Bucket()).Put([]byte(dto.AccessToken), src)
})
if err = repo.db.Update(func(tx *bolt.Tx) error {
if err := tx.Bucket(dto.Bucket()).Put([]byte(dto.AccessToken), src); err != nil {
return errors.Wrap(err, "failed to overwrite the token in the bucket")
}
return nil
}); err != nil {
return errors.Wrap(err, "failed to update the token in the repository")
}
return nil
}
func (repo *boltTokenRepository) Remove(ctx context.Context, accessToken string) error {
return repo.db.Update(func(tx *bolt.Tx) error {
return tx.Bucket(Token{}.Bucket()).Delete([]byte(accessToken))
})
if err := repo.db.Update(func(tx *bolt.Tx) error {
//nolint: exhaustivestruct
if err := tx.Bucket(Token{}.Bucket()).Delete([]byte(accessToken)); err != nil {
return errors.Wrap(err, "failed to remove token in bucket")
}
return nil
}); err != nil {
return errors.Wrap(err, "failed to remove token from storage")
}
return nil
}
func NewToken() *Token {
@ -113,7 +130,7 @@ func (t *Token) Populate(src *model.Token) {
func (t *Token) Bind(src []byte, dst *model.Token) error {
if err := json.Unmarshal(src, t); err != nil {
return err
return errors.Wrap(err, "cannot unmarshal token source")
}
dst.AccessToken = t.AccessToken

View File

@ -1,3 +1,4 @@
//nolint: wrapcheck
package bolt_test
import (
@ -11,13 +12,13 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.etcd.io/bbolt"
"source.toby3d.me/website/oauth/internal/model"
"source.toby3d.me/website/oauth/internal/random"
"source.toby3d.me/website/oauth/internal/token"
"source.toby3d.me/website/oauth/internal/token/repository/bolt"
)
//nolint: gochecknoglobals
var (
db *bbolt.DB
repo token.Repository
@ -51,6 +52,7 @@ func TestGet(t *testing.T) {
t.Cleanup(func() {
_ = db.Update(func(tx *bbolt.Tx) error {
//nolint: exhaustivestruct
return tx.Bucket(bolt.Token{}.Bucket()).Delete([]byte(accessToken))
})
})
@ -65,6 +67,7 @@ func TestGet(t *testing.T) {
require.NoError(t, err)
require.NoError(t, db.Update(func(tx *bbolt.Tx) error {
//nolint: exhaustivestruct
return tx.Bucket(bolt.Token{}.Bucket()).Put([]byte(accessToken), src)
}))
@ -76,6 +79,7 @@ func TestGet(t *testing.T) {
Me: "https://toby3d.me/",
Scopes: []string{"read", "update", "delete"},
Type: "Bearer",
Profile: nil,
}, tkn)
}
@ -86,6 +90,7 @@ func TestCreate(t *testing.T) {
t.Cleanup(func() {
_ = db.Update(func(tx *bbolt.Tx) error {
//nolint: exhaustivestruct
return tx.Bucket(bolt.Token{}.Bucket()).Delete([]byte(accessToken))
})
})
@ -96,12 +101,15 @@ func TestCreate(t *testing.T) {
Me: "https://toby3d.me/",
Scopes: []string{"read", "update", "delete"},
Type: "Bearer",
Profile: nil,
}
require.NoError(t, repo.Create(context.TODO(), tkn))
result := model.NewToken()
require.NoError(t, db.View(func(tx *bbolt.Tx) error {
//nolint: exhaustivestruct
return bolt.NewToken().Bind(tx.Bucket(bolt.Token{}.Bucket()).Get([]byte(tkn.AccessToken)), result)
}))
assert.Equal(t, tkn, result)
@ -116,6 +124,7 @@ func TestUpdate(t *testing.T) {
t.Cleanup(func() {
_ = db.Update(func(tx *bbolt.Tx) error {
//nolint: exhaustivestruct
return tx.Bucket(bolt.Token{}.Bucket()).Delete([]byte(accessToken))
})
})
@ -130,6 +139,7 @@ func TestUpdate(t *testing.T) {
require.NoError(t, err)
require.NoError(t, db.Update(func(tx *bbolt.Tx) error {
//nolint: exhaustivestruct
return tx.Bucket(bolt.Token{}.Bucket()).Put([]byte(accessToken), src)
}))
@ -139,10 +149,13 @@ func TestUpdate(t *testing.T) {
Me: "https://toby3d.ru/",
Scopes: []string{"read"},
Type: "Bearer",
Profile: nil,
}))
result := model.NewToken()
require.NoError(t, db.View(func(tx *bbolt.Tx) error {
//nolint: exhaustivestruct
return bolt.NewToken().Bind(tx.Bucket(bolt.Token{}.Bucket()).Get([]byte(accessToken)), result)
}))
assert.Equal(t, &model.Token{
@ -151,6 +164,7 @@ func TestUpdate(t *testing.T) {
Me: "https://toby3d.ru/",
Scopes: []string{"read"},
Type: "Bearer",
Profile: nil,
}, result)
}
@ -161,6 +175,7 @@ func TestDelete(t *testing.T) {
t.Cleanup(func() {
_ = db.Update(func(tx *bbolt.Tx) error {
//nolint: exhaustivestruct
return tx.Bucket(bolt.Token{}.Bucket()).Delete([]byte(accessToken))
})
})
@ -175,12 +190,14 @@ func TestDelete(t *testing.T) {
require.NoError(t, err)
require.NoError(t, db.Update(func(tx *bbolt.Tx) error {
//nolint: exhaustivestruct
return tx.Bucket(bolt.Token{}.Bucket()).Put([]byte(accessToken), src)
}))
require.NoError(t, repo.Remove(context.TODO(), accessToken))
require.NoError(t, db.View(func(tx *bbolt.Tx) error {
//nolint: exhaustivestruct
assert.Nil(t, tx.Bucket(bolt.Token{}.Bucket()).Get([]byte(accessToken)))
return nil

View File

@ -7,7 +7,6 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"source.toby3d.me/website/oauth/internal/model"
"source.toby3d.me/website/oauth/internal/random"
"source.toby3d.me/website/oauth/internal/token"

View File

@ -3,6 +3,7 @@ package usecase
import (
"context"
"github.com/pkg/errors"
"source.toby3d.me/website/oauth/internal/model"
"source.toby3d.me/website/oauth/internal/token"
)
@ -18,9 +19,18 @@ func NewTokenUseCase(tokens token.Repository) token.UseCase {
}
func (useCase *tokenUseCase) Verify(ctx context.Context, accessToken string) (*model.Token, error) {
return useCase.tokens.Get(ctx, accessToken)
t, err := useCase.tokens.Get(ctx, accessToken)
if err != nil {
return nil, errors.Wrap(err, "failed to retrieve token from storage")
}
return t, nil
}
func (useCase *tokenUseCase) Revoke(ctx context.Context, accessToken string) error {
return useCase.tokens.Remove(ctx, accessToken)
if err := useCase.tokens.Remove(ctx, accessToken); err != nil {
return errors.Wrap(err, "failed to delete a token in the vault")
}
return nil
}

View File

@ -8,7 +8,6 @@ import (
"github.com/brianvoe/gofakeit"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"source.toby3d.me/website/oauth/internal/model"
repository "source.toby3d.me/website/oauth/internal/token/repository/memory"
"source.toby3d.me/website/oauth/internal/token/usecase"
@ -28,6 +27,7 @@ func TestVerify(t *testing.T) {
ClientID: "https://app.example.com/",
Me: "https://user.example.net/",
Scopes: []string{"create", "update", "delete"},
Profile: nil,
}
require.NoError(repo.Create(context.TODO(), accessToken))
@ -53,6 +53,7 @@ func TestRevoke(t *testing.T) {
ClientID: "https://app.example.com/",
Me: "https://user.example.net/",
Scopes: []string{"create", "update", "delete"},
Profile: nil,
}))
token, err := repo.Get(context.TODO(), accessToken)