Skip to content

Commit 057973d

Browse files
authored
Merge pull request #11 from LyricTian/develop
To optimize implements
2 parents 4bec7fd + 806c31d commit 057973d

File tree

16 files changed

+407
-405
lines changed

16 files changed

+407
-405
lines changed

README.md

+12-4
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,15 @@ import (
2424

2525
"gopkg.in/oauth2.v3/manage"
2626
"gopkg.in/oauth2.v3/server"
27-
"gopkg.in/oauth2.v3/store/token"
27+
"gopkg.in/oauth2.v3/store"
2828
)
2929

3030
func main() {
31-
manager := manage.NewRedisManager(
32-
&token.RedisConfig{Addr: "192.168.33.70:6379"},
33-
)
31+
manager := manage.NewDefaultManager()
32+
manager.MapTokenStorage(store.NewMemoryTokenStore(0))
33+
// client test store
34+
manager.MapClientStorage(store.NewTestClientStore())
35+
3436
srv := server.NewServer(server.NewConfig(), manager)
3537
srv.SetUserAuthorizationHandler(func(w http.ResponseWriter, r *http.Request) (userID string, err error) {
3638
// validation and to get the user id
@@ -73,6 +75,12 @@ Example
7375

7476
Simulation examples of authorization code model, please check [example](/example)
7577

78+
Token storage implements
79+
------------------------
80+
81+
* [Redis](https://github.com/go-oauth2/redis)
82+
* [MongoDB](https://github.com/go-oauth2/mongo)
83+
7684
License
7785
-------
7886

errors/error.go

-29
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,6 @@ package errors
22

33
import "errors"
44

5-
var (
6-
// ErrUnauthorizedClient unauthorized client
7-
ErrUnauthorizedClient = errors.New("unauthorized_client")
8-
9-
// ErrAccessDenied access denied
10-
ErrAccessDenied = errors.New("access_denied")
11-
12-
// ErrUnsupportedResponseType unsupported response type
13-
ErrUnsupportedResponseType = errors.New("unsupported_response_type")
14-
15-
// ErrInvalidScope invalid scope
16-
ErrInvalidScope = errors.New("invalid_scope")
17-
18-
// ErrInvalidRequest invalid request
19-
ErrInvalidRequest = errors.New("invalid_request")
20-
21-
// ErrInvalidClient invalid client
22-
ErrInvalidClient = errors.New("invalid_client")
23-
24-
// ErrInvalidGrant invalid grant
25-
ErrInvalidGrant = errors.New("invalid_grant")
26-
27-
// ErrUnsupportedGrantType unsupported grant type
28-
ErrUnsupportedGrantType = errors.New("unsupported_grant_type")
29-
30-
// ErrServerError server error
31-
ErrServerError = errors.New("server_error")
32-
)
33-
345
var (
356
// ErrNilValue Nil Value
367
ErrNilValue = errors.New("nil value")

errors/response.go

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package errors
2+
3+
import "errors"
4+
5+
// Response error response
6+
type Response struct {
7+
Error error `json:"error"`
8+
Description string `json:"error_description,omitempty"`
9+
URI string `json:"error_uri,omitempty"`
10+
StatusCode int `json:"-"`
11+
}
12+
13+
var (
14+
// ErrInvalidRequest invalid request
15+
ErrInvalidRequest = errors.New("invalid_request")
16+
17+
// ErrUnauthorizedClient unauthorized client
18+
ErrUnauthorizedClient = errors.New("unauthorized_client")
19+
20+
// ErrAccessDenied access denied
21+
ErrAccessDenied = errors.New("access_denied")
22+
23+
// ErrUnsupportedResponseType unsupported response type
24+
ErrUnsupportedResponseType = errors.New("unsupported_response_type")
25+
26+
// ErrInvalidScope invalid scope
27+
ErrInvalidScope = errors.New("invalid_scope")
28+
29+
// ErrServerError server error
30+
ErrServerError = errors.New("server_error")
31+
32+
// ErrTemporarilyUnavailable temporarily unavailable
33+
ErrTemporarilyUnavailable = errors.New("temporarily_unavailable")
34+
35+
// ErrInvalidClient invalid client
36+
ErrInvalidClient = errors.New("invalid_client")
37+
38+
// ErrInvalidGrant invalid grant
39+
ErrInvalidGrant = errors.New("invalid_grant")
40+
41+
// ErrUnsupportedGrantType unsupported grant type
42+
ErrUnsupportedGrantType = errors.New("unsupported_grant_type")
43+
)
44+
45+
// Descriptions error description
46+
var Descriptions = map[error]string{
47+
ErrInvalidRequest: "The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed",
48+
ErrUnauthorizedClient: "The client is not authorized to request an authorization code using this method",
49+
ErrAccessDenied: "The resource owner or authorization server denied the request",
50+
ErrUnsupportedResponseType: "The authorization server does not support obtaining an authorization code using this method",
51+
ErrInvalidScope: "The requested scope is invalid, unknown, or malformed",
52+
ErrServerError: "The authorization server encountered an unexpected condition that prevented it from fulfilling the request",
53+
ErrTemporarilyUnavailable: "The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server",
54+
ErrInvalidClient: "Client authentication failed",
55+
ErrInvalidGrant: "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client",
56+
ErrUnsupportedGrantType: "The authorization grant type is not supported by the authorization server",
57+
}

example/server/main.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import (
1010
"gopkg.in/oauth2.v3/manage"
1111
"gopkg.in/oauth2.v3/models"
1212
"gopkg.in/oauth2.v3/server"
13-
"gopkg.in/oauth2.v3/store/client"
14-
"gopkg.in/oauth2.v3/store/token"
13+
"gopkg.in/oauth2.v3/store"
14+
1515
"gopkg.in/session.v1"
1616
)
1717

@@ -25,19 +25,19 @@ func init() {
2525
}
2626

2727
func main() {
28-
manager := manage.NewRedisManager(
29-
&token.RedisConfig{Addr: "192.168.33.70:6379"},
30-
)
31-
// Create the client temporary storage
32-
manager.MapClientStorage(client.NewTempStore(&models.Client{
28+
manager := manage.NewDefaultManager()
29+
// token store
30+
manager.MapTokenStorage(store.NewMemoryTokenStore(0))
31+
// client store
32+
manager.MapClientStorage(store.NewTestClientStore(&models.Client{
3333
ID: "222222",
3434
Secret: "22222222",
3535
Domain: "http://localhost:9094",
3636
}))
3737

3838
srv := server.NewServer(server.NewConfig(), manager)
3939
srv.SetUserAuthorizationHandler(userAuthorizeHandler)
40-
srv.SetErrorHandler(func(err error) {
40+
srv.SetInternalErrorHandler(func(err error) {
4141
fmt.Println("OAuth2 Error:", err.Error())
4242
})
4343

manage/manage_test.go

+5-15
Original file line numberDiff line numberDiff line change
@@ -4,35 +4,25 @@ import (
44
"testing"
55

66
"gopkg.in/oauth2.v3"
7-
"gopkg.in/oauth2.v3/generates"
87
"gopkg.in/oauth2.v3/manage"
9-
"gopkg.in/oauth2.v3/models"
10-
"gopkg.in/oauth2.v3/store/client"
11-
"gopkg.in/oauth2.v3/store/token"
8+
"gopkg.in/oauth2.v3/store"
129

1310
. "github.com/smartystreets/goconvey/convey"
1411
)
1512

1613
func TestManager(t *testing.T) {
1714
Convey("Manager test", t, func() {
18-
manager := manage.NewManager()
19-
20-
manager.MapClientModel(models.NewClient())
21-
manager.MapTokenModel(models.NewToken())
22-
manager.MapAuthorizeGenerate(generates.NewAuthorizeGenerate())
23-
manager.MapAccessGenerate(generates.NewAccessGenerate())
24-
manager.MapClientStorage(client.NewTempStore())
15+
manager := manage.NewDefaultManager()
16+
manager.MapClientStorage(store.NewTestClientStore())
2517

2618
Convey("GetClient test", func() {
2719
cli, err := manager.GetClient("1")
2820
So(err, ShouldBeNil)
2921
So(cli.GetSecret(), ShouldEqual, "11")
3022
})
3123

32-
Convey("Redis store test", func() {
33-
manager.MustTokenStorage(token.NewRedisStore(
34-
&token.RedisConfig{Addr: "192.168.33.70:6379"},
35-
))
24+
Convey("Memory store test", func() {
25+
manager.MapTokenStorage(store.NewMemoryTokenStore(0))
3626
testManager(manager)
3727
})
3828
})

manage/manager.go

+33-31
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ import (
55

66
"github.com/LyricTian/inject"
77

8+
"reflect"
9+
810
"gopkg.in/oauth2.v3"
911
"gopkg.in/oauth2.v3/errors"
1012
"gopkg.in/oauth2.v3/generates"
1113
"gopkg.in/oauth2.v3/models"
12-
"gopkg.in/oauth2.v3/store/token"
1314
)
1415

1516
// Config Configuration parameters
@@ -19,31 +20,30 @@ type Config struct {
1920
IsGenerateRefresh bool // Whether to generate the refreshing token
2021
}
2122

22-
// NewRedisManager Create to based on redis store authorization management instance
23-
func NewRedisManager(redisCfg *token.RedisConfig) *Manager {
23+
// NewDefaultManager Create to default authorization management instance
24+
func NewDefaultManager() *Manager {
2425
m := NewManager()
25-
m.MapClientModel(models.NewClient())
26+
27+
// default config
28+
m.SetAuthorizeCodeExp(time.Minute * 10)
29+
m.SetImplicitTokenExp(time.Hour * 1)
30+
m.SetClientTokenExp(time.Hour * 2)
31+
m.SetAuthorizeCodeTokenCfg(&Config{IsGenerateRefresh: true, AccessTokenExp: time.Hour * 2, RefreshTokenExp: time.Hour * 24 * 3})
32+
m.SetPasswordTokenCfg(&Config{IsGenerateRefresh: true, AccessTokenExp: time.Hour * 2, RefreshTokenExp: time.Hour * 24 * 7})
33+
2634
m.MapTokenModel(models.NewToken())
2735
m.MapAuthorizeGenerate(generates.NewAuthorizeGenerate())
2836
m.MapAccessGenerate(generates.NewAccessGenerate())
29-
m.MustTokenStorage(token.NewRedisStore(redisCfg))
3037

3138
return m
3239
}
3340

3441
// NewManager Create to authorization management instance
3542
func NewManager() *Manager {
36-
m := &Manager{
43+
return &Manager{
3744
injector: inject.New(),
3845
gtcfg: make(map[oauth2.GrantType]*Config),
3946
}
40-
m.SetAuthorizeCodeExp(time.Minute * 10)
41-
m.SetAuthorizeCodeTokenExp(&Config{IsGenerateRefresh: true, AccessTokenExp: time.Hour * 2, RefreshTokenExp: time.Hour * 24 * 3})
42-
m.SetImplicitTokenExp(&Config{AccessTokenExp: time.Hour * 1})
43-
m.SetPasswordTokenExp(&Config{IsGenerateRefresh: true, AccessTokenExp: time.Hour * 2, RefreshTokenExp: time.Hour * 24 * 7})
44-
m.SetClientTokenExp(&Config{AccessTokenExp: time.Hour * 2})
45-
46-
return m
4747
}
4848

4949
// Manager Provide authorization management
@@ -53,38 +53,38 @@ type Manager struct {
5353
gtcfg map[oauth2.GrantType]*Config // Authorization grant configuration
5454
}
5555

56+
func (m *Manager) newTokenInfo(ti oauth2.TokenInfo) oauth2.TokenInfo {
57+
in := reflect.ValueOf(ti)
58+
if in.IsNil() {
59+
return ti
60+
}
61+
out := reflect.New(in.Type().Elem())
62+
return out.Interface().(oauth2.TokenInfo)
63+
}
64+
5665
// SetAuthorizeCodeExp Set the authorization code expiration time
5766
func (m *Manager) SetAuthorizeCodeExp(exp time.Duration) {
5867
m.codeExp = exp
5968
}
6069

61-
// SetAuthorizeCodeTokenExp Set the authorization code grant token expiration time
62-
func (m *Manager) SetAuthorizeCodeTokenExp(cfg *Config) {
70+
// SetAuthorizeCodeTokenCfg Set the authorization code grant token config
71+
func (m *Manager) SetAuthorizeCodeTokenCfg(cfg *Config) {
6372
m.gtcfg[oauth2.AuthorizationCode] = cfg
6473
}
6574

6675
// SetImplicitTokenExp Set the implicit grant token expiration time
67-
func (m *Manager) SetImplicitTokenExp(cfg *Config) {
68-
m.gtcfg[oauth2.Implicit] = cfg
76+
func (m *Manager) SetImplicitTokenExp(exp time.Duration) {
77+
m.gtcfg[oauth2.Implicit] = &Config{AccessTokenExp: exp}
6978
}
7079

71-
// SetPasswordTokenExp Set the password grant token expiration time
72-
func (m *Manager) SetPasswordTokenExp(cfg *Config) {
80+
// SetPasswordTokenCfg Set the password grant token config
81+
func (m *Manager) SetPasswordTokenCfg(cfg *Config) {
7382
m.gtcfg[oauth2.PasswordCredentials] = cfg
7483
}
7584

7685
// SetClientTokenExp Set the client grant token expiration time
77-
func (m *Manager) SetClientTokenExp(cfg *Config) {
78-
m.gtcfg[oauth2.ClientCredentials] = cfg
79-
}
80-
81-
// MapClientModel Mapping the client information model
82-
func (m *Manager) MapClientModel(cli oauth2.ClientInfo) error {
83-
if cli == nil {
84-
return errors.ErrNilValue
85-
}
86-
m.injector.Map(cli)
87-
return nil
86+
func (m *Manager) SetClientTokenExp(exp time.Duration) {
87+
m.gtcfg[oauth2.ClientCredentials] = &Config{AccessTokenExp: exp}
8888
}
8989

9090
// MapTokenModel Mapping the token information model
@@ -137,7 +137,7 @@ func (m *Manager) MustClientStorage(stor oauth2.ClientStore, err error) {
137137
// MapTokenStorage Mapping the token store interface
138138
func (m *Manager) MapTokenStorage(stor oauth2.TokenStore) error {
139139
if stor == nil {
140-
return (errors.ErrNilValue)
140+
return errors.ErrNilValue
141141
}
142142
m.injector.Map(stor)
143143
return nil
@@ -180,6 +180,7 @@ func (m *Manager) GenerateAuthToken(rt oauth2.ResponseType, tgr *oauth2.TokenGen
180180
return
181181
}
182182
_, ierr := m.injector.Invoke(func(ti oauth2.TokenInfo, gen oauth2.AuthorizeGenerate, tgen oauth2.AccessGenerate, stor oauth2.TokenStore) {
183+
ti = m.newTokenInfo(ti)
183184
var (
184185
tv string
185186
terr error
@@ -247,6 +248,7 @@ func (m *Manager) GenerateAccessToken(gt oauth2.GrantType, tgr *oauth2.TokenGene
247248
return
248249
}
249250
_, ierr := m.injector.Invoke(func(ti oauth2.TokenInfo, gen oauth2.AccessGenerate, stor oauth2.TokenStore) {
251+
ti = m.newTokenInfo(ti)
250252
td := &oauth2.GenerateBasic{
251253
Client: cli,
252254
UserID: tgr.UserID,

models/client.go

-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
package models
22

3-
// NewClient Create to client model instance
4-
func NewClient() *Client {
5-
return &Client{}
6-
}
7-
83
// Client Client model
94
type Client struct {
105
ID string // The client id

server/handler.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@ type PasswordAuthorizationHandler func(username, password string) (userID string
2525
// RefreshingScopeHandler Check the scope of the refreshing token
2626
type RefreshingScopeHandler func(newScope, oldScope string) (allowed bool)
2727

28-
// ErrorHandler Error handling
29-
type ErrorHandler func(err error)
28+
// ResponseErrorHandler Response error handing
29+
type ResponseErrorHandler func(re *errors.Response)
30+
31+
// InternalErrorHandler Internal error handing
32+
type InternalErrorHandler func(err error)
3033

3134
// ClientFormHandler Get client data from form
3235
func ClientFormHandler(r *http.Request) (clientID, clientSecret string, err error) {

0 commit comments

Comments
 (0)