Skip to content

Commit fb84906

Browse files
authored
feat: use redisadapter.NewAdapter(config) now (#51)
1 parent 00e084b commit fb84906

File tree

5 files changed

+358
-71
lines changed

5 files changed

+358
-71
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@ jobs:
2424
run: go test -v -coverprofile=profile.cov ./...
2525

2626
- name: Install goveralls
27-
env:
28-
GO111MODULE: off
29-
run: go get github.com/mattn/goveralls
27+
run: go install github.com/mattn/[email protected]
3028

3129
- name: Send coverage
3230
env:

README.md

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,21 @@ Redis Adapter is the [Redis](https://redis.io/) adapter for [Casbin](https://git
1515

1616
go get github.com/casbin/redis-adapter/v3
1717

18-
## Simple Example
18+
## Configuration Options
19+
20+
The `Config` struct supports the following options:
21+
22+
- `Network` (string): Network type, e.g., "tcp", "unix" (required when not using Pool)
23+
- `Address` (string): Redis server address, e.g., "127.0.0.1:6379" (required when not using Pool)
24+
- `Key` (string): Redis key to store Casbin rules (default: "casbin_rules")
25+
- `Username` (string): Username for Redis authentication (optional)
26+
- `Password` (string): Password for Redis authentication (optional)
27+
- `TLSConfig` (*tls.Config): TLS configuration for secure connections (optional)
28+
- `Pool` (*redis.Pool): Existing Redis connection pool (optional, if provided, other connection options are ignored)
29+
30+
## Usage Examples
31+
32+
### Basic Usage
1933

2034
```go
2135
package main
@@ -26,28 +40,23 @@ import (
2640
)
2741

2842
func main() {
29-
// Direct Initialization:
30-
// Initialize a Redis adapter and use it in a Casbin enforcer:
31-
a, _ := redisadapter.NewAdapter("tcp", "127.0.0.1:6379") // Your Redis network and address.
43+
// Recommended approach using Config
44+
config := &redisadapter.Config{Network: "tcp", Address: "127.0.0.1:6379"}
45+
a, _ := redisadapter.NewAdapter(config)
3246

33-
// Use the following if Redis has password like "123"
34-
// a, err := redisadapter.NewAdapterWithPassword("tcp", "127.0.0.1:6379", "123")
47+
// With password authentication
48+
// config := &redisadapter.Config{Network: "tcp", Address: "127.0.0.1:6379", Password: "123"}
49+
// a, _ := redisadapter.NewAdapter(config)
3550

36-
// Use the following if you use Redis with a specific user
37-
// a, err := redisadapter.NewAdapterWithUser("tcp", "127.0.0.1:6379", "username", "password")
51+
// With user credentials
52+
// config := &redisadapter.Config{Network: "tcp", Address: "127.0.0.1:6379", Username: "user", Password: "pass"}
53+
// a, _ := redisadapter.NewAdapter(config)
3854

39-
// Use the following if you use Redis connections pool
40-
// pool := &redis.Pool{}
41-
// a, err := redisadapter.NewAdapterWithPool(pool)
42-
43-
// Initialization with different user options:
44-
// Use the following if you use Redis with passowrd like "123":
45-
// a, err := redisadapter.NewAdapterWithOption(redisadapter.WithNetwork("tcp"), redisadapter.WithAddress("127.0.0.1:6379"), redisadapter.WithPassword("123"))
46-
47-
// Use the following if you use Redis with username, password, and TLS option:
55+
// With TLS configuration
4856
// var clientTLSConfig tls.Config
4957
// ...
50-
// a, err := redisadapter.NewAdapterWithOption(redisadapter.WithNetwork("tcp"), redisadapter.WithAddress("127.0.0.1:6379"), redisadapter.WithUsername("testAccount"), redisadapter.WithPassword("123456"), redisadapter.WithTls(&clientTLSConfig))
58+
// config := &redisadapter.Config{Network: "tcp", Address: "127.0.0.1:6379", Username: "testAccount", Password: "123456", TLSConfig: &clientTLSConfig}
59+
// a, _ := redisadapter.NewAdapter(config)
5160

5261
e, _ := casbin.NewEnforcer("examples/rbac_model.conf", a)
5362

@@ -66,6 +75,35 @@ func main() {
6675
}
6776
```
6877

78+
### With Connection Pool
79+
80+
```go
81+
package main
82+
83+
import (
84+
"github.com/casbin/casbin/v2"
85+
"github.com/casbin/redis-adapter/v3"
86+
"github.com/gomodule/redigo/redis"
87+
)
88+
89+
func main() {
90+
pool := &redis.Pool{Dial: func() (redis.Conn, error) { return redis.Dial("tcp", "127.0.0.1:6379") }}
91+
config := &redisadapter.Config{Pool: pool, Key: "casbin_rules"}
92+
a, _ := redisadapter.NewAdapter(config)
93+
94+
e, _ := casbin.NewEnforcer("examples/rbac_model.conf", a)
95+
96+
// Load the policy from DB.
97+
e.LoadPolicy()
98+
99+
// Check the permission.
100+
e.Enforce("alice", "data1", "read")
101+
102+
// Save the policy back to DB.
103+
e.SavePolicy()
104+
}
105+
```
106+
69107
## Getting Help
70108

71109
- [Casbin](https://github.com/casbin/casbin)

adapter.go

Lines changed: 123 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,25 @@ type CasbinRule struct {
4040
V5 string
4141
}
4242

43+
// Config represents the configuration for the Redis adapter.
44+
type Config struct {
45+
// Network is the network type, e.g., "tcp", "unix"
46+
Network string
47+
// Address is the Redis server address, e.g., "127.0.0.1:6379"
48+
Address string
49+
// Key is the Redis key to store Casbin rules (default: "casbin_rules")
50+
Key string
51+
// Username for Redis authentication (optional)
52+
Username string
53+
// Password for Redis authentication (optional)
54+
Password string
55+
// TLSConfig for secure connections (optional)
56+
TLSConfig *tls.Config
57+
// Pool is an existing Redis connection pool (optional)
58+
// If provided, Network, Address, Username, Password, and TLSConfig are ignored
59+
Pool *redis.Pool
60+
}
61+
4362
// Adapter represents the Redis adapter for policy storage.
4463
type Adapter struct {
4564
network string
@@ -78,94 +97,148 @@ func finalizer(a *Adapter) {
7897
}
7998
}
8099

81-
func newAdapter(network string, address string, key string,
82-
username string, password string) (*Adapter, error) {
100+
// NewAdapter creates a new Redis adapter with the provided configuration.
101+
func NewAdapter(config *Config) (*Adapter, error) {
102+
if config == nil {
103+
return nil, errors.New("config cannot be nil")
104+
}
105+
83106
a := &Adapter{}
84-
a.network = network
85-
a.address = address
86-
a.key = key
87-
a.username = username
88-
a.password = password
89107

90-
// Open the DB, create it if not existed.
91-
err := a.open()
108+
// Set default key if not provided
109+
if config.Key == "" {
110+
a.key = "casbin_rules"
111+
} else {
112+
a.key = config.Key
113+
}
114+
115+
// If a pool is provided, use it
116+
if config.Pool != nil {
117+
a._pool = config.Pool
118+
} else {
119+
// Otherwise, create a new connection
120+
if config.Network == "" {
121+
return nil, errors.New("network is required when not using a pool")
122+
}
123+
if config.Address == "" {
124+
return nil, errors.New("address is required when not using a pool")
125+
}
126+
127+
a.network = config.Network
128+
a.address = config.Address
129+
a.username = config.Username
130+
a.password = config.Password
131+
a.tlsConfig = config.TLSConfig
132+
133+
// Open the DB connection
134+
err := a.open()
135+
if err != nil {
136+
return nil, err
137+
}
138+
}
92139

93140
// Call the destructor when the object is released.
94141
runtime.SetFinalizer(a, finalizer)
95142

96-
return a, err
143+
return a, nil
97144
}
98145

99-
// NewAdapter is the constructor for Adapter.
100-
func NewAdapter(network string, address string) (*Adapter, error) {
101-
return newAdapter(network, address, "casbin_rules", "", "")
146+
// Legacy constructor functions (deprecated)
147+
// These are kept for backward compatibility but should be avoided in new code
148+
149+
// NewAdapterBasic is the basic constructor for Adapter.
150+
// Deprecated: Use NewAdapter with Config struct instead.
151+
func NewAdapterBasic(network string, address string) (*Adapter, error) {
152+
config := &Config{
153+
Network: network,
154+
Address: address,
155+
}
156+
return NewAdapter(config)
102157
}
103158

159+
// NewAdapterWithUser creates adapter with user credentials.
160+
// Deprecated: Use NewAdapter with Config struct instead.
104161
func NewAdapterWithUser(network string, address string, username string, password string) (*Adapter, error) {
105-
return newAdapter(network, address, "casbin_rules", username, password)
162+
config := &Config{
163+
Network: network,
164+
Address: address,
165+
Username: username,
166+
Password: password,
167+
}
168+
return NewAdapter(config)
106169
}
107170

108-
// NewAdapterWithPassword is the constructor for Adapter.
171+
// NewAdapterWithPassword creates adapter with password authentication.
172+
// Deprecated: Use NewAdapter with Config struct instead.
109173
func NewAdapterWithPassword(network string, address string, password string) (*Adapter, error) {
110-
return newAdapter(network, address, "casbin_rules", "", password)
174+
config := &Config{
175+
Network: network,
176+
Address: address,
177+
Password: password,
178+
}
179+
return NewAdapter(config)
111180
}
112181

113-
// NewAdapterWithKey is the constructor for Adapter.
182+
// NewAdapterWithKey creates adapter with custom key.
183+
// Deprecated: Use NewAdapter with Config struct instead.
114184
func NewAdapterWithKey(network string, address string, key string) (*Adapter, error) {
115-
return newAdapter(network, address, key, "", "")
185+
config := &Config{
186+
Network: network,
187+
Address: address,
188+
Key: key,
189+
}
190+
return NewAdapter(config)
116191
}
117192

118-
// NewAdapterWithPool is the constructor for Adapter.
193+
// NewAdapterWithPool creates adapter with connection pool.
194+
// Deprecated: Use NewAdapter with Config struct instead.
119195
func NewAdapterWithPool(pool *redis.Pool) (*Adapter, error) {
120-
a := &Adapter{}
121-
a.key = "casbin_rules"
122-
123-
conn := pool.Get()
124-
defer a.release(conn)
125-
126-
a._conn = conn
127-
a._pool = pool
128-
129-
// Call the destructor when the object is released.
130-
runtime.SetFinalizer(a, finalizer)
131-
132-
return a, nil
196+
config := &Config{
197+
Pool: pool,
198+
}
199+
return NewAdapter(config)
133200
}
134201

135-
// NewAdapterWithPoolAndOptions is the constructor for Adapter.
202+
// NewAdapterWithPoolAndOptions creates adapter with pool and options.
203+
// Deprecated: Use NewAdapter with Config struct instead.
136204
func NewAdapterWithPoolAndOptions(pool *redis.Pool, options ...Option) (*Adapter, error) {
137-
a := &Adapter{}
138-
a.key = "casbin_rules"
205+
config := &Config{
206+
Pool: pool,
207+
}
208+
a, err := NewAdapter(config)
209+
if err != nil {
210+
return nil, err
211+
}
212+
213+
// Apply options for backward compatibility
139214
for _, option := range options {
140215
option(a)
141216
}
142217

143-
conn := pool.Get()
144-
defer a.release(conn)
145-
146-
a._conn = conn
147-
a._pool = pool
148-
149-
// Call the destructor when the object is released.
150-
runtime.SetFinalizer(a, finalizer)
151-
152218
return a, nil
153219
}
154220

155221
type Option func(*Adapter)
156222

223+
// NewAdapterWithOption creates adapter with options pattern.
224+
// Deprecated: Use NewAdapter with Config struct instead.
157225
func NewAdapterWithOption(options ...Option) (*Adapter, error) {
158226
a := &Adapter{}
159227
for _, option := range options {
160228
option(a)
161229
}
162-
// Open the DB, create it if not existed.
163-
err := a.open()
164230

165-
// Call the destructor when the object is released.
166-
runtime.SetFinalizer(a, finalizer)
231+
// Convert to new config-based approach
232+
config := &Config{
233+
Network: a.network,
234+
Address: a.address,
235+
Key: a.key,
236+
Username: a.username,
237+
Password: a.password,
238+
TLSConfig: a.tlsConfig,
239+
}
167240

168-
return a, err
241+
return NewAdapter(config)
169242
}
170243

171244
func WithAddress(address string) Option {
@@ -191,6 +264,7 @@ func WithNetwork(network string) Option {
191264
a.network = network
192265
}
193266
}
267+
194268
func WithKey(key string) Option {
195269
return func(a *Adapter) {
196270
a.key = key

0 commit comments

Comments
 (0)