Skip to content

Commit

Permalink
Merge pull request #680 from couchbase/feature/issue_666
Browse files Browse the repository at this point in the history
Config to allow empty passwords
  • Loading branch information
snej committed Feb 26, 2015
2 parents 4287106 + e59540c commit 6a7cb80
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 20 deletions.
3 changes: 0 additions & 3 deletions src/github.com/couchbase/sync_gateway/auth/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,6 @@ func (user *userImpl) validate() error {
return base.HTTPErrorf(http.StatusBadRequest, "Invalid email address")
} else if user.OldPasswordHash_ != nil {
return base.HTTPErrorf(http.StatusBadRequest, "Obsolete password hash present")
} else if (user.Name_ == "") != (user.PasswordHash_ == nil) {
// Real user must have a password; anon user must not have a password
return base.HTTPErrorf(http.StatusBadRequest, "Invalid password")
}
for roleName, _ := range user.ExplicitRoles_ {
if !IsValidPrincipalName(roleName) {
Expand Down
1 change: 1 addition & 0 deletions src/github.com/couchbase/sync_gateway/db/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type DatabaseContext struct {
revisionCache *RevisionCache // Cache of recently-accessed doc revisions
changeCache changeCache //
EventMgr *EventManager // Manages notification events
AllowEmptyPassword bool // Allow empty passwords? Defaults to false
}

const DefaultRevsLimit = 1000
Expand Down
27 changes: 25 additions & 2 deletions src/github.com/couchbase/sync_gateway/db/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,28 @@ type PrincipalConfig struct {
RoleNames []string `json:"roles,omitempty"`
}

// Check if the password in this PrincipalConfig is valid. Only allow
// empty passwords if allowEmptyPass is true.
func (p PrincipalConfig) IsPasswordValid(allowEmptyPass bool) (isValid bool, reason string) {

// if it's an anon user, they should not have a password
if p.Name == nil && p.Password != nil {
return false, "Anonymous users should not have a password"
}

if allowEmptyPass {
// allow any password, skip validation
return true, ""
}

if p.Password != nil && len(*p.Password) < 3 {
return false, "Passwords must be at least three 3 characters"
}

return true, ""

}

func (dbc *DatabaseContext) GetPrincipal(name string, isUser bool) (info *PrincipalConfig, err error) {
var princ auth.Principal
if isUser {
Expand Down Expand Up @@ -55,8 +77,9 @@ func (dbc *DatabaseContext) UpdatePrincipal(newInfo PrincipalConfig, isUser bool
var user auth.User
authenticator := dbc.Authenticator()
if isUser {
if newInfo.Password != nil && len(*(newInfo.Password)) < 3 {
err = base.HTTPErrorf(http.StatusBadRequest, "Passwords must be at least three 3 characters")
isValid, reason := newInfo.IsPasswordValid(dbc.AllowEmptyPassword)
if !isValid {
err = base.HTTPErrorf(http.StatusBadRequest, reason)
return
}
user, err = authenticator.GetUser(*newInfo.Name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ import (
"testing"
"time"

"github.com/couchbaselabs/go.assert"
"github.com/couchbase/sync_gateway/auth"
"github.com/couchbase/sync_gateway/channels"
"github.com/couchbase/sync_gateway/db"
"github.com/couchbaselabs/go.assert"
)

func TestUserAPI(t *testing.T) {
Expand Down
29 changes: 15 additions & 14 deletions src/github.com/couchbase/sync_gateway/rest/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,20 +72,21 @@ type ServerConfig struct {

// JSON object that defines a database configuration within the ServerConfig.
type DbConfig struct {
Name string `json:"name"` // Database name in REST API (stored as key in JSON)
Server *string `json:"server"` // Couchbase (or Walrus) server URL, default "http://localhost:8091"
Username string `json:"username,omitempty"` // Username for authenticating to server
Password string `json:"password,omitempty"` // Password for authenticating to server
Bucket *string `json:"bucket"` // Bucket name on server; defaults to same as 'name'
Pool *string `json:"pool"` // Couchbase pool name, default "default"
Sync *string `json:"sync"` // Sync function defines which users can see which data
Users map[string]*db.PrincipalConfig `json:"users,omitempty"` // Initial user accounts
Roles map[string]*db.PrincipalConfig `json:"roles,omitempty"` // Initial roles
RevsLimit *uint32 `json:"revs_limit,omitempty"` // Max depth a document's revision tree can grow to
ImportDocs interface{} `json:"import_docs,omitempty"` // false, true, or "continuous"
Shadow *ShadowConfig `json:"shadow,omitempty"` // External bucket to shadow
EventHandlers *EventHandlerConfig `json:"event_handlers,omitempty"` // Event handlers (webhook)
FeedType string `json:"feed_type,omitempty"` // Feed type - "DCP" or "TAP"; defaults based on Couchbase server version
Name string `json:"name"` // Database name in REST API (stored as key in JSON)
Server *string `json:"server"` // Couchbase (or Walrus) server URL, default "http://localhost:8091"
Username string `json:"username,omitempty"` // Username for authenticating to server
Password string `json:"password,omitempty"` // Password for authenticating to server
Bucket *string `json:"bucket"` // Bucket name on server; defaults to same as 'name'
Pool *string `json:"pool"` // Couchbase pool name, default "default"
Sync *string `json:"sync"` // Sync function defines which users can see which data
Users map[string]*db.PrincipalConfig `json:"users,omitempty"` // Initial user accounts
Roles map[string]*db.PrincipalConfig `json:"roles,omitempty"` // Initial roles
RevsLimit *uint32 `json:"revs_limit,omitempty"` // Max depth a document's revision tree can grow to
ImportDocs interface{} `json:"import_docs,omitempty"` // false, true, or "continuous"
Shadow *ShadowConfig `json:"shadow,omitempty"` // External bucket to shadow
EventHandlers *EventHandlerConfig `json:"event_handlers,omitempty"` // Event handlers (webhook)
FeedType string `json:"feed_type,omitempty"` // Feed type - "DCP" or "TAP"; defaults based on Couchbase server version
AllowEmptyPassword bool `json:"allow_empty_password,omitempty"` // Allow empty passwords? Defaults to false
}

type DbConfigMap map[string]*DbConfig
Expand Down
2 changes: 2 additions & 0 deletions src/github.com/couchbase/sync_gateway/rest/server_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ func (sc *ServerContext) getOrAddDatabaseFromConfig(config *DbConfig, useExistin
dbcontext.RevsLimit = *config.RevsLimit
}

dbcontext.AllowEmptyPassword = config.AllowEmptyPassword

if dbcontext.ChannelMapper == nil {
base.Logf("Using default sync function 'channel(doc.channels)' for database %q", dbName)
}
Expand Down

0 comments on commit 6a7cb80

Please sign in to comment.