🚨 Removed linter warnings for token
This commit is contained in:
parent
bb1d908c9a
commit
a8bc4587ed
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue