Skip to content

Commit

Permalink
Merge pull request #1 from FeNoMeNa/client_store
Browse files Browse the repository at this point in the history
clients: implement ClientStore interface
  • Loading branch information
LyricTian authored Dec 19, 2019
2 parents 3d506d2 + ee5bd5a commit 49d1e0f
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 22 deletions.
126 changes: 126 additions & 0 deletions client_store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package mongo

import (
"github.com/globalsign/mgo"
"gopkg.in/oauth2.v3"
"gopkg.in/oauth2.v3/models"
)

// ClientConfig client configuration parameters
type ClientConfig struct {
// store clients data collection name(The default is oauth2_clients)
ClientsCName string
}

// NewDefaultClientConfig create a default client configuration
func NewDefaultClientConfig() *ClientConfig {
return &ClientConfig{
ClientsCName: "oauth2_clients",
}
}

// NewClientStore create a client store instance based on mongodb
func NewClientStore(cfg *Config, ccfgs ...*ClientConfig) *ClientStore {
session, err := mgo.Dial(cfg.URL)
if err != nil {
panic(err)
}

return NewClientStoreWithSession(session, cfg.DB, ccfgs...)
}

// NewClientStoreWithSession create a client store instance based on mongodb
func NewClientStoreWithSession(session *mgo.Session, dbName string, ccfgs ...*ClientConfig) *ClientStore {
cs := &ClientStore{
dbName: dbName,
session: session,
ccfg: NewDefaultClientConfig(),
}
if len(ccfgs) > 0 {
cs.ccfg = ccfgs[0]
}

return cs
}

// ClientStore MongoDB storage for OAuth 2.0
type ClientStore struct {
ccfg *ClientConfig
dbName string
session *mgo.Session
}

// Close close the mongo session
func (cs *ClientStore) Close() {
cs.session.Close()
}

func (cs *ClientStore) c(name string) *mgo.Collection {
return cs.session.DB(cs.dbName).C(name)
}

func (cs *ClientStore) cHandler(name string, handler func(c *mgo.Collection)) {
session := cs.session.Clone()
defer session.Close()
handler(session.DB(cs.dbName).C(name))
return
}

// Set set client information
func (cs *ClientStore) Set(info oauth2.ClientInfo) (err error) {
cs.cHandler(cs.ccfg.ClientsCName, func(c *mgo.Collection) {
entity := &client{
ID: info.GetID(),
Secret: info.GetSecret(),
Domain: info.GetDomain(),
UserID: info.GetUserID(),
}

if cerr := c.Insert(entity); cerr != nil {
err = cerr
return
}
})

return
}

// GetByID according to the ID for the client information
func (cs *ClientStore) GetByID(id string) (info oauth2.ClientInfo, err error) {
cs.cHandler(cs.ccfg.ClientsCName, func(c *mgo.Collection) {
entity := new(client)

if cerr := c.FindId(id).One(entity); cerr != nil {
err = cerr
return
}

info = &models.Client{
ID: entity.ID,
Secret: entity.Secret,
Domain: entity.Domain,
UserID: entity.UserID,
}
})

return
}

// RemoveByID use the client id to delete the client information
func (cs *ClientStore) RemoveByID(id string) (err error) {
cs.cHandler(cs.ccfg.ClientsCName, func(c *mgo.Collection) {
if cerr := c.RemoveId(id); cerr != nil {
err = cerr
return
}
})

return
}

type client struct {
ID string `bson:"_id"`
Secret string `bson:"secret"`
Domain string `bson:"domain"`
UserID string `bson:"userid"`
}
64 changes: 64 additions & 0 deletions client_store_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package mongo

import (
"testing"

. "github.com/smartystreets/goconvey/convey"
"gopkg.in/oauth2.v3/models"
)

func TestClientStore(t *testing.T) {
store := NewClientStore(NewConfig(url, dbName))

client := &models.Client{
ID: "id",
Secret: "secret",
Domain: "domain",
UserID: "user_id",
}

Convey("Set", t, func() {
Convey("HappyPath", func() {
_ = store.RemoveByID(client.ID)

err := store.Set(client)

So(err, ShouldBeNil)
})

Convey("AlreadyExistingClient", func() {
_ = store.RemoveByID(client.ID)

_ = store.Set(client)
err := store.Set(client)

So(err, ShouldNotBeNil)
})
})

Convey("GetByID", t, func() {
Convey("HappyPath", func() {
_ = store.RemoveByID(client.ID)
_ = store.Set(client)

got, err := store.GetByID(client.ID)

So(err, ShouldBeNil)
So(got, ShouldResemble, client)
})

Convey("UnknownClient", func() {
_, err := store.GetByID("unknown_client")

So(err, ShouldNotBeNil)
})
})

Convey("RemoveByID", t, func() {
Convey("UnknownClient", func() {
err := store.RemoveByID("unknown_client")

So(err, ShouldNotBeNil)
})
})
}
15 changes: 15 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package mongo

// Config mongodb configuration parameters
type Config struct {
URL string
DB string
}

// NewConfig create mongodb configuration
func NewConfig(url, db string) *Config {
return &Config{
URL: url,
DB: db,
}
}
6 changes: 6 additions & 0 deletions config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package mongo

const (
url = "127.0.0.1:27017"
dbName = "mydb_test"
)
20 changes: 3 additions & 17 deletions mongo.go → token_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,6 @@ import (
"gopkg.in/oauth2.v3/models"
)

// Config mongodb configuration parameters
type Config struct {
URL string
DB string
}

// NewConfig create mongodb configuration
func NewConfig(url, db string) *Config {
return &Config{
URL: url,
DB: db,
}
}

// TokenConfig token configuration parameters
type TokenConfig struct {
// store txn collection name(The default is oauth2)
Expand Down Expand Up @@ -68,17 +54,17 @@ func NewTokenStoreWithSession(session *mgo.Session, dbName string, tcfgs ...*Tok
ts.tcfg = tcfgs[0]
}

ts.c(ts.tcfg.BasicCName).EnsureIndex(mgo.Index{
_ = ts.c(ts.tcfg.BasicCName).EnsureIndex(mgo.Index{
Key: []string{"ExpiredAt"},
ExpireAfter: time.Second * 1,
})

ts.c(ts.tcfg.AccessCName).EnsureIndex(mgo.Index{
_ = ts.c(ts.tcfg.AccessCName).EnsureIndex(mgo.Index{
Key: []string{"ExpiredAt"},
ExpireAfter: time.Second * 1,
})

ts.c(ts.tcfg.RefreshCName).EnsureIndex(mgo.Index{
_ = ts.c(ts.tcfg.RefreshCName).EnsureIndex(mgo.Index{
Key: []string{"ExpiredAt"},
ExpireAfter: time.Second * 1,
})
Expand Down
5 changes: 0 additions & 5 deletions mongo_test.go → token_store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@ import (
. "github.com/smartystreets/goconvey/convey"
)

const (
url = "127.0.0.1:27017"
dbName = "mydb_test"
)

func TestTokenStore(t *testing.T) {
Convey("Test mongodb token store", t, func() {
store := NewTokenStore(NewConfig(url, dbName))
Expand Down

0 comments on commit 49d1e0f

Please sign in to comment.