func marshalPrincipal(princ auth.Principal) ([]byte, error) { name := externalUserName(princ.Name()) info := PrincipalJSON{ Name: &name, ExplicitChannels: princ.ExplicitChannels().AsSet(), Channels: princ.Channels().AsSet(), } if user, ok := princ.(auth.User); ok { info.Email = user.Email() info.Disabled = user.Disabled() info.ExplicitRoleNames = user.ExplicitRoleNames() info.RoleNames = user.RoleNames() } return json.Marshal(info) }
// Common behavior of putUser and putRole func putPrincipal(r http.ResponseWriter, rq *http.Request, context *context, name string, princ auth.Principal) error { context.auth.InvalidateChannels(princ) if rq.Method == "POST" { name = princ.Name() if name == "" { return &base.HTTPError{http.StatusBadRequest, "Missing name property"} } } else if princ.Name() != name { return &base.HTTPError{http.StatusBadRequest, "Name mismatch (can't change name)"} } err := context.auth.Save(princ) if err == nil { r.WriteHeader(http.StatusCreated) } return err }
// Recomputes the set of channels a User/Role has been granted access to by sync() functions. // This is part of the ChannelComputer interface defined by the Authenticator. func (context *DatabaseContext) ComputeChannelsForPrincipal(princ auth.Principal) (channels.TimedSet, error) { key := princ.Name() if _, ok := princ.(auth.User); !ok { key = "role:" + key // Roles are identified in access view by a "role:" prefix } var vres struct { Rows []struct { Value channels.TimedSet } } opts := map[string]interface{}{"stale": false, "key": key} if verr := context.Bucket.ViewCustom("sync_gateway", "access", opts, &vres); verr != nil { return nil, verr } channelSet := channels.TimedSet{} for _, row := range vres.Rows { channelSet.Add(row.Value) } return channelSet, nil }