github.com/go-kivik/kivik/v4@v4.3.2/x/kivikd/authdb/couchauth/couchauth.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 2 // use this file except in compliance with the License. You may obtain a copy of 3 // the License at 4 // 5 // http://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 // License for the specific language governing permissions and limitations under 11 // the License. 12 13 // Package couchauth provides auth services to a remote CouchDB server. 14 package couchauth 15 16 import ( 17 "context" 18 "encoding/json" 19 "errors" 20 "net/http" 21 "net/url" 22 23 "github.com/go-kivik/kivik/v4/couchdb/chttp" 24 "github.com/go-kivik/kivik/v4/x/kivikd/authdb" 25 ) 26 27 type client struct { 28 *chttp.Client 29 } 30 31 var _ authdb.UserStore = &client{} 32 33 // New returns a new auth user store, which authenticates users against a remote 34 // CouchDB server. 35 func New(dsn string) (authdb.UserStore, error) { 36 p, err := url.Parse(dsn) 37 if err != nil { 38 return nil, err 39 } 40 if p.User != nil { 41 return nil, errors.New("DSN must not contain authentication credentials") 42 } 43 c, err := chttp.New(&http.Client{}, dsn, nil) 44 return &client{c}, err 45 } 46 47 func (c *client) Validate(ctx context.Context, username, password string) (*authdb.UserContext, error) { 48 req, err := c.NewRequest(ctx, http.MethodGet, "/_session", nil, nil) 49 if err != nil { 50 return nil, err 51 } 52 req.SetBasicAuth(username, password) 53 resp, err := c.Do(req) 54 if err != nil { 55 return nil, err 56 } 57 if err = chttp.ResponseError(resp); err != nil { 58 return nil, err 59 } 60 result := struct { 61 Ctx struct { 62 Name string `json:"name"` 63 Roles []string `json:"roles"` 64 } 65 }{} 66 defer resp.Body.Close() 67 dec := json.NewDecoder(resp.Body) 68 if err = dec.Decode(&result); err != nil { 69 return nil, err 70 } 71 return &authdb.UserContext{ 72 Name: result.Ctx.Name, 73 Roles: result.Ctx.Roles, 74 Salt: "", // FIXME 75 }, nil 76 } 77 78 func (c *client) UserCtx(context.Context, string) (*authdb.UserContext, error) { 79 // var result struct { 80 // Ctx struct { 81 // Roles []string `json:"roles"` 82 // } `json:"userCtx"` 83 // } 84 // return result.Ctx.Roles, c.DoJSON() 85 return nil, nil 86 }