-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GOCBC-256: Use new core callbacks for authentication.
Motivation ---------- Due to the ongoing use of the Go SDK by teams internally within Couchbase. There is a need for enabling developers to utilize the internal server authentication method. Changes ------- Updated SDK to utilize the new authentication callback API exposed by gocbcore to enable use of the internal authentication service. Change-Id: I0a9813e5abc0cc48c26318d08ec013a0d72f0435 Reviewed-on: http://review.couchbase.org/87078 Reviewed-by: Sergey Avseyev <sergey.avseyev@gmail.com> Tested-by: Brett Lawson <brett19@gmail.com>
- Loading branch information
Showing
8 changed files
with
181 additions
and
151 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,137 +1,125 @@ | ||
package gocb | ||
|
||
// Authenticator provides an interface to authenticate to each service. | ||
type Authenticator interface { | ||
clusterMgmt() userPassPair | ||
clusterN1ql() []userPassPair | ||
clusterFts() []userPassPair | ||
bucketMemd(bucket string) userPassPair | ||
bucketMgmt(bucket string) userPassPair | ||
bucketViews(bucket string) userPassPair | ||
bucketN1ql(bucket string) []userPassPair | ||
bucketFts(bucket string) []userPassPair | ||
} | ||
import "gopkg.in/couchbase/gocbcore.v7" | ||
|
||
// BucketAuthenticator provides a password for a single bucket. | ||
type BucketAuthenticator struct { | ||
Password string | ||
} | ||
// UserPassPair represents a username and password pair. | ||
type UserPassPair gocbcore.UserPassPair | ||
|
||
type userPassPair struct { | ||
Username string `json:"user"` | ||
Password string `json:"pass"` | ||
type coreAuthWrapper struct { | ||
auth Authenticator | ||
bucketName string | ||
} | ||
|
||
// BucketAuthenticatorMap is a map of bucket name to BucketAuthenticator. | ||
type BucketAuthenticatorMap map[string]BucketAuthenticator | ||
|
||
// ClusterAuthenticator implements an Authenticator which uses a list of buckets and passwords. | ||
type ClusterAuthenticator struct { | ||
Buckets BucketAuthenticatorMap | ||
Username string | ||
Password string | ||
} | ||
|
||
func (ca ClusterAuthenticator) clusterMgmt() userPassPair { | ||
return userPassPair{ca.Username, ca.Password} | ||
} | ||
|
||
func (ca ClusterAuthenticator) clusterAll() []userPassPair { | ||
userPassList := make([]userPassPair, len(ca.Buckets)) | ||
for bucket, auth := range ca.Buckets { | ||
userPassList = append(userPassList, userPassPair{ | ||
Username: bucket, | ||
Password: auth.Password, | ||
}) | ||
// Credentials returns the credentials for a particular service. | ||
func (auth *coreAuthWrapper) Credentials(req gocbcore.AuthCredsRequest) ([]gocbcore.UserPassPair, error) { | ||
creds, err := auth.auth.Credentials(AuthCredsRequest{ | ||
Service: ServiceType(req.Service), | ||
Endpoint: req.Endpoint, | ||
Bucket: auth.bucketName, | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return userPassList | ||
} | ||
|
||
func (ca ClusterAuthenticator) clusterN1ql() []userPassPair { | ||
return ca.clusterAll() | ||
coreCreds := make([]gocbcore.UserPassPair, len(creds)) | ||
for credIdx, userPass := range creds { | ||
coreCreds[credIdx] = gocbcore.UserPassPair(userPass) | ||
} | ||
return coreCreds, nil | ||
} | ||
|
||
func (ca ClusterAuthenticator) clusterFts() []userPassPair { | ||
return ca.clusterAll() | ||
// AuthCredsRequest encapsulates the data for a credential request | ||
// from the new Authenticator interface. | ||
// UNCOMMITTED | ||
type AuthCredsRequest struct { | ||
Service ServiceType | ||
Endpoint string | ||
Bucket string | ||
} | ||
|
||
func (ca ClusterAuthenticator) bucketAll(bucket string) userPassPair { | ||
if bucketAuth, ok := ca.Buckets[bucket]; ok { | ||
return userPassPair{bucket, bucketAuth.Password} | ||
func getSingleCredential(auth Authenticator, req AuthCredsRequest) (UserPassPair, error) { | ||
creds, err := auth.Credentials(req) | ||
if err != nil { | ||
return UserPassPair{}, err | ||
} | ||
return userPassPair{"", ""} | ||
} | ||
|
||
func (ca ClusterAuthenticator) bucketMemd(bucket string) userPassPair { | ||
return ca.bucketAll(bucket) | ||
} | ||
if len(creds) != 1 { | ||
return UserPassPair{}, gocbcore.ErrInvalidCredentials | ||
} | ||
|
||
func (ca ClusterAuthenticator) bucketMgmt(bucket string) userPassPair { | ||
return ca.bucketAll(bucket) | ||
return creds[0], nil | ||
} | ||
|
||
func (ca ClusterAuthenticator) bucketViews(bucket string) userPassPair { | ||
return ca.bucketAll(bucket) | ||
// Authenticator provides an interface to authenticate to each service. Note that | ||
// only authenticators implemented here are stable, and support for custom | ||
// authenticators is considered volatile. | ||
type Authenticator interface { | ||
Credentials(req AuthCredsRequest) ([]UserPassPair, error) | ||
} | ||
|
||
func (ca ClusterAuthenticator) bucketN1ql(bucket string) []userPassPair { | ||
return []userPassPair{ | ||
ca.bucketAll(bucket), | ||
} | ||
// BucketAuthenticator provides a password for a single bucket. | ||
type BucketAuthenticator struct { | ||
Password string | ||
} | ||
|
||
func (ca ClusterAuthenticator) bucketFts(bucket string) []userPassPair { | ||
return []userPassPair{ | ||
ca.bucketAll(bucket), | ||
} | ||
} | ||
// BucketAuthenticatorMap is a map of bucket name to BucketAuthenticator. | ||
type BucketAuthenticatorMap map[string]BucketAuthenticator | ||
|
||
// PasswordAuthenticator implements an Authenticator which uses an RBAC username and password. | ||
type PasswordAuthenticator struct { | ||
// ClusterAuthenticator implements an Authenticator which uses a list of buckets and passwords. | ||
type ClusterAuthenticator struct { | ||
Buckets BucketAuthenticatorMap | ||
Username string | ||
Password string | ||
} | ||
|
||
func (ra PasswordAuthenticator) rbacAll() userPassPair { | ||
return userPassPair{ra.Username, ra.Password} | ||
func (ca ClusterAuthenticator) clusterCreds() []UserPassPair { | ||
var creds []UserPassPair | ||
for bucketName, bucket := range ca.Buckets { | ||
creds = append(creds, UserPassPair{ | ||
Username: bucketName, | ||
Password: bucket.Password, | ||
}) | ||
} | ||
return creds | ||
} | ||
|
||
func (ra PasswordAuthenticator) clusterMgmt() userPassPair { | ||
return ra.rbacAll() | ||
} | ||
// Credentials returns the credentials for a particular service. | ||
func (ca ClusterAuthenticator) Credentials(req AuthCredsRequest) ([]UserPassPair, error) { | ||
if req.Bucket == "" { | ||
if req.Service == MemdService || req.Service == MgmtService || | ||
req.Service == CapiService { | ||
return []UserPassPair{{ | ||
Username: ca.Username, | ||
Password: ca.Password, | ||
}}, nil | ||
} | ||
|
||
func (ra PasswordAuthenticator) clusterN1ql() []userPassPair { | ||
return []userPassPair{ | ||
ra.rbacAll(), | ||
return ca.clusterCreds(), nil | ||
} | ||
} | ||
|
||
func (ra PasswordAuthenticator) clusterFts() []userPassPair { | ||
return []userPassPair{ | ||
ra.rbacAll(), | ||
if bucketAuth, ok := ca.Buckets[req.Bucket]; ok { | ||
return []UserPassPair{{ | ||
Username: req.Bucket, | ||
Password: bucketAuth.Password, | ||
}}, nil | ||
} | ||
} | ||
|
||
func (ra PasswordAuthenticator) bucketMemd(bucket string) userPassPair { | ||
return ra.rbacAll() | ||
} | ||
|
||
func (ra PasswordAuthenticator) bucketMgmt(bucket string) userPassPair { | ||
return ra.rbacAll() | ||
} | ||
|
||
func (ra PasswordAuthenticator) bucketViews(bucket string) userPassPair { | ||
return ra.rbacAll() | ||
return []UserPassPair{{ | ||
Username: "", | ||
Password: "", | ||
}}, nil | ||
} | ||
|
||
func (ra PasswordAuthenticator) bucketN1ql(bucket string) []userPassPair { | ||
return []userPassPair{ | ||
ra.rbacAll(), | ||
} | ||
// PasswordAuthenticator implements an Authenticator which uses an RBAC username and password. | ||
type PasswordAuthenticator struct { | ||
Username string | ||
Password string | ||
} | ||
|
||
func (ra PasswordAuthenticator) bucketFts(bucket string) []userPassPair { | ||
return []userPassPair{ | ||
ra.rbacAll(), | ||
} | ||
// Credentials returns the credentials for a particular service. | ||
func (ra PasswordAuthenticator) Credentials(req AuthCredsRequest) ([]UserPassPair, error) { | ||
return []UserPassPair{{ | ||
Username: ra.Username, | ||
Password: ra.Password, | ||
}}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.