Skip to content

Commit 49d1e0f

Browse files
authored
Merge pull request #1 from FeNoMeNa/client_store
clients: implement ClientStore interface
2 parents 3d506d2 + ee5bd5a commit 49d1e0f

6 files changed

+214
-22
lines changed

client_store.go

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
package mongo
2+
3+
import (
4+
"github.com/globalsign/mgo"
5+
"gopkg.in/oauth2.v3"
6+
"gopkg.in/oauth2.v3/models"
7+
)
8+
9+
// ClientConfig client configuration parameters
10+
type ClientConfig struct {
11+
// store clients data collection name(The default is oauth2_clients)
12+
ClientsCName string
13+
}
14+
15+
// NewDefaultClientConfig create a default client configuration
16+
func NewDefaultClientConfig() *ClientConfig {
17+
return &ClientConfig{
18+
ClientsCName: "oauth2_clients",
19+
}
20+
}
21+
22+
// NewClientStore create a client store instance based on mongodb
23+
func NewClientStore(cfg *Config, ccfgs ...*ClientConfig) *ClientStore {
24+
session, err := mgo.Dial(cfg.URL)
25+
if err != nil {
26+
panic(err)
27+
}
28+
29+
return NewClientStoreWithSession(session, cfg.DB, ccfgs...)
30+
}
31+
32+
// NewClientStoreWithSession create a client store instance based on mongodb
33+
func NewClientStoreWithSession(session *mgo.Session, dbName string, ccfgs ...*ClientConfig) *ClientStore {
34+
cs := &ClientStore{
35+
dbName: dbName,
36+
session: session,
37+
ccfg: NewDefaultClientConfig(),
38+
}
39+
if len(ccfgs) > 0 {
40+
cs.ccfg = ccfgs[0]
41+
}
42+
43+
return cs
44+
}
45+
46+
// ClientStore MongoDB storage for OAuth 2.0
47+
type ClientStore struct {
48+
ccfg *ClientConfig
49+
dbName string
50+
session *mgo.Session
51+
}
52+
53+
// Close close the mongo session
54+
func (cs *ClientStore) Close() {
55+
cs.session.Close()
56+
}
57+
58+
func (cs *ClientStore) c(name string) *mgo.Collection {
59+
return cs.session.DB(cs.dbName).C(name)
60+
}
61+
62+
func (cs *ClientStore) cHandler(name string, handler func(c *mgo.Collection)) {
63+
session := cs.session.Clone()
64+
defer session.Close()
65+
handler(session.DB(cs.dbName).C(name))
66+
return
67+
}
68+
69+
// Set set client information
70+
func (cs *ClientStore) Set(info oauth2.ClientInfo) (err error) {
71+
cs.cHandler(cs.ccfg.ClientsCName, func(c *mgo.Collection) {
72+
entity := &client{
73+
ID: info.GetID(),
74+
Secret: info.GetSecret(),
75+
Domain: info.GetDomain(),
76+
UserID: info.GetUserID(),
77+
}
78+
79+
if cerr := c.Insert(entity); cerr != nil {
80+
err = cerr
81+
return
82+
}
83+
})
84+
85+
return
86+
}
87+
88+
// GetByID according to the ID for the client information
89+
func (cs *ClientStore) GetByID(id string) (info oauth2.ClientInfo, err error) {
90+
cs.cHandler(cs.ccfg.ClientsCName, func(c *mgo.Collection) {
91+
entity := new(client)
92+
93+
if cerr := c.FindId(id).One(entity); cerr != nil {
94+
err = cerr
95+
return
96+
}
97+
98+
info = &models.Client{
99+
ID: entity.ID,
100+
Secret: entity.Secret,
101+
Domain: entity.Domain,
102+
UserID: entity.UserID,
103+
}
104+
})
105+
106+
return
107+
}
108+
109+
// RemoveByID use the client id to delete the client information
110+
func (cs *ClientStore) RemoveByID(id string) (err error) {
111+
cs.cHandler(cs.ccfg.ClientsCName, func(c *mgo.Collection) {
112+
if cerr := c.RemoveId(id); cerr != nil {
113+
err = cerr
114+
return
115+
}
116+
})
117+
118+
return
119+
}
120+
121+
type client struct {
122+
ID string `bson:"_id"`
123+
Secret string `bson:"secret"`
124+
Domain string `bson:"domain"`
125+
UserID string `bson:"userid"`
126+
}

client_store_test.go

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package mongo
2+
3+
import (
4+
"testing"
5+
6+
. "github.com/smartystreets/goconvey/convey"
7+
"gopkg.in/oauth2.v3/models"
8+
)
9+
10+
func TestClientStore(t *testing.T) {
11+
store := NewClientStore(NewConfig(url, dbName))
12+
13+
client := &models.Client{
14+
ID: "id",
15+
Secret: "secret",
16+
Domain: "domain",
17+
UserID: "user_id",
18+
}
19+
20+
Convey("Set", t, func() {
21+
Convey("HappyPath", func() {
22+
_ = store.RemoveByID(client.ID)
23+
24+
err := store.Set(client)
25+
26+
So(err, ShouldBeNil)
27+
})
28+
29+
Convey("AlreadyExistingClient", func() {
30+
_ = store.RemoveByID(client.ID)
31+
32+
_ = store.Set(client)
33+
err := store.Set(client)
34+
35+
So(err, ShouldNotBeNil)
36+
})
37+
})
38+
39+
Convey("GetByID", t, func() {
40+
Convey("HappyPath", func() {
41+
_ = store.RemoveByID(client.ID)
42+
_ = store.Set(client)
43+
44+
got, err := store.GetByID(client.ID)
45+
46+
So(err, ShouldBeNil)
47+
So(got, ShouldResemble, client)
48+
})
49+
50+
Convey("UnknownClient", func() {
51+
_, err := store.GetByID("unknown_client")
52+
53+
So(err, ShouldNotBeNil)
54+
})
55+
})
56+
57+
Convey("RemoveByID", t, func() {
58+
Convey("UnknownClient", func() {
59+
err := store.RemoveByID("unknown_client")
60+
61+
So(err, ShouldNotBeNil)
62+
})
63+
})
64+
}

config.go

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package mongo
2+
3+
// Config mongodb configuration parameters
4+
type Config struct {
5+
URL string
6+
DB string
7+
}
8+
9+
// NewConfig create mongodb configuration
10+
func NewConfig(url, db string) *Config {
11+
return &Config{
12+
URL: url,
13+
DB: db,
14+
}
15+
}

config_test.go

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package mongo
2+
3+
const (
4+
url = "127.0.0.1:27017"
5+
dbName = "mydb_test"
6+
)

mongo.go renamed to token_store.go

+3-17
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,6 @@ import (
1111
"gopkg.in/oauth2.v3/models"
1212
)
1313

14-
// Config mongodb configuration parameters
15-
type Config struct {
16-
URL string
17-
DB string
18-
}
19-
20-
// NewConfig create mongodb configuration
21-
func NewConfig(url, db string) *Config {
22-
return &Config{
23-
URL: url,
24-
DB: db,
25-
}
26-
}
27-
2814
// TokenConfig token configuration parameters
2915
type TokenConfig struct {
3016
// store txn collection name(The default is oauth2)
@@ -68,17 +54,17 @@ func NewTokenStoreWithSession(session *mgo.Session, dbName string, tcfgs ...*Tok
6854
ts.tcfg = tcfgs[0]
6955
}
7056

71-
ts.c(ts.tcfg.BasicCName).EnsureIndex(mgo.Index{
57+
_ = ts.c(ts.tcfg.BasicCName).EnsureIndex(mgo.Index{
7258
Key: []string{"ExpiredAt"},
7359
ExpireAfter: time.Second * 1,
7460
})
7561

76-
ts.c(ts.tcfg.AccessCName).EnsureIndex(mgo.Index{
62+
_ = ts.c(ts.tcfg.AccessCName).EnsureIndex(mgo.Index{
7763
Key: []string{"ExpiredAt"},
7864
ExpireAfter: time.Second * 1,
7965
})
8066

81-
ts.c(ts.tcfg.RefreshCName).EnsureIndex(mgo.Index{
67+
_ = ts.c(ts.tcfg.RefreshCName).EnsureIndex(mgo.Index{
8268
Key: []string{"ExpiredAt"},
8369
ExpireAfter: time.Second * 1,
8470
})

mongo_test.go renamed to token_store_test.go

-5
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,6 @@ import (
99
. "github.com/smartystreets/goconvey/convey"
1010
)
1111

12-
const (
13-
url = "127.0.0.1:27017"
14-
dbName = "mydb_test"
15-
)
16-
1712
func TestTokenStore(t *testing.T) {
1813
Convey("Test mongodb token store", t, func() {
1914
store := NewTokenStore(NewConfig(url, dbName))

0 commit comments

Comments
 (0)