github.com/go-kivik/kivik/v4@v4.3.2/couchdb/chttp/basicauth.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 chttp 14 15 import ( 16 "fmt" 17 "net/http" 18 "strings" 19 20 "github.com/go-kivik/kivik/v4" 21 ) 22 23 // BasicAuth provides HTTP Basic Auth for a client. 24 type basicAuth struct { 25 Username string 26 Password string 27 28 // transport stores the original transport that is overridden by this auth 29 // mechanism 30 transport http.RoundTripper 31 } 32 33 var ( 34 _ authenticator = &basicAuth{} 35 _ kivik.Option = (*basicAuth)(nil) 36 ) 37 38 func (a *basicAuth) Apply(target interface{}) { 39 if auth, ok := target.(*authenticator); ok { 40 // Clone this so that it's safe to re-use the same option to multiple 41 // client connections. TODO: This can no doubt be refactored. 42 *auth = &basicAuth{ 43 Username: a.Username, 44 Password: a.Password, 45 } 46 } 47 } 48 49 func (a *basicAuth) String() string { 50 return fmt.Sprintf("[BasicAuth{user:%s,pass:%s}]", a.Username, strings.Repeat("*", len(a.Password))) 51 } 52 53 // RoundTrip fulfills the http.RoundTripper interface. It sets HTTP Basic Auth 54 // on outbound requests. 55 func (a *basicAuth) RoundTrip(req *http.Request) (*http.Response, error) { 56 req.SetBasicAuth(a.Username, a.Password) 57 return a.transport.RoundTrip(req) 58 } 59 60 // Authenticate sets HTTP Basic Auth headers for the client. 61 func (a *basicAuth) Authenticate(c *Client) error { 62 a.transport = c.Transport 63 if a.transport == nil { 64 a.transport = http.DefaultTransport 65 } 66 c.Transport = a 67 return nil 68 } 69 70 type jwtAuth struct { 71 Token string 72 73 transport http.RoundTripper 74 } 75 76 var _ kivik.Option = (*jwtAuth)(nil) 77 78 func (a *jwtAuth) Apply(target interface{}) { 79 if auth, ok := target.(*authenticator); ok { 80 // Clone this so that it's safe to re-use the same option to multiple 81 // client connections. TODO: This can no doubt be refactored. 82 *auth = &jwtAuth{ 83 Token: a.Token, 84 } 85 } 86 } 87 88 func (a *jwtAuth) String() string { 89 token := a.Token 90 const unmaskedLen = 3 91 if len(token) > unmaskedLen { 92 token = token[:unmaskedLen] + strings.Repeat("*", len(token)-unmaskedLen) 93 } 94 return fmt.Sprintf("[JWTAuth{token:%s}]", token) 95 } 96 97 // RoundTrip satisfies the http.RoundTripper interface. 98 func (a *jwtAuth) RoundTrip(req *http.Request) (*http.Response, error) { 99 req.Header.Set("Authorization", "Bearer "+a.Token) 100 return a.transport.RoundTrip(req) 101 } 102 103 // Authenticate performs authentication against CouchDB. 104 func (a *jwtAuth) Authenticate(c *Client) error { 105 a.transport = c.Transport 106 if a.transport == nil { 107 a.transport = http.DefaultTransport 108 } 109 c.Transport = a 110 return nil 111 }