mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 16:12:24 -05:00 
			
		
		
		
	Grand test fixup (#138)
* start fixing up tests * fix up tests + automate with drone * fiddle with linting * messing about with drone.yml * some more fiddling * hmmm * add cache * add vendor directory * verbose * ci updates * update some little things * update sig
This commit is contained in:
		
					parent
					
						
							
								329a5e8144
							
						
					
				
			
			
				commit
				
					
						98263a7de6
					
				
			
		
					 2677 changed files with 1090869 additions and 219 deletions
				
			
		
							
								
								
									
										14
									
								
								vendor/github.com/quasoft/memstore/.gitignore
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/quasoft/memstore/.gitignore
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # Binaries for programs and plugins | ||||
| *.exe | ||||
| *.dll | ||||
| *.so | ||||
| *.dylib | ||||
| 
 | ||||
| # Test binary, build with `go test -c` | ||||
| *.test | ||||
| 
 | ||||
| # Output of the go coverage tool, specifically when used with LiteIDE | ||||
| *.out | ||||
| 
 | ||||
| # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 | ||||
| .glide/ | ||||
							
								
								
									
										8
									
								
								vendor/github.com/quasoft/memstore/.travis.yml
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/quasoft/memstore/.travis.yml
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,8 @@ | |||
| language: go | ||||
| sudo: false | ||||
| go: | ||||
|   - tip | ||||
| before_install: | ||||
|   - go get github.com/mattn/goveralls | ||||
| script: | ||||
|   - $GOPATH/bin/goveralls -service=travis-ci | ||||
							
								
								
									
										29
									
								
								vendor/github.com/quasoft/memstore/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								vendor/github.com/quasoft/memstore/LICENSE
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | |||
| BSD 3-Clause License | ||||
| 
 | ||||
| Copyright (c) 2018, QuaSoft | ||||
| All rights reserved. | ||||
| 
 | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are met: | ||||
| 
 | ||||
| * Redistributions of source code must retain the above copyright notice, this | ||||
|   list of conditions and the following disclaimer. | ||||
| 
 | ||||
| * Redistributions in binary form must reproduce the above copyright notice, | ||||
|   this list of conditions and the following disclaimer in the documentation | ||||
|   and/or other materials provided with the distribution. | ||||
| 
 | ||||
| * Neither the name of the copyright holder nor the names of its | ||||
|   contributors may be used to endorse or promote products derived from | ||||
|   this software without specific prior written permission. | ||||
| 
 | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||||
| DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||||
| FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||||
| DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||||
| SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||||
| CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||||
| OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
							
								
								
									
										74
									
								
								vendor/github.com/quasoft/memstore/README.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								vendor/github.com/quasoft/memstore/README.md
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,74 @@ | |||
| # memstore | ||||
| 
 | ||||
| [](https://godoc.org/github.com/quasoft/memstore) [](https://travis-ci.org/quasoft/memstore) [](https://coveralls.io/github/quasoft/memstore?branch=master) [](https://goreportcard.com/report/github.com/quasoft/memstore) | ||||
| 
 | ||||
| In-memory implementation of [gorilla/sessions](https://github.com/gorilla/sessions) for use in tests and dev environments | ||||
| 
 | ||||
| ## How to install | ||||
| 
 | ||||
|     go get github.com/quasoft/memstore | ||||
| 
 | ||||
| ## Documentation | ||||
| 
 | ||||
| Documentation, as usual, can be found at [godoc.org](http://www.godoc.org/github.com/quasoft/memstore). | ||||
| 
 | ||||
| The interface of [gorilla/sessions](https://github.com/gorilla/sessions) is described at http://www.gorillatoolkit.org/pkg/sessions. | ||||
| 
 | ||||
| ### How to use | ||||
| ``` go | ||||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"log" | ||||
| 	"net/http" | ||||
| 
 | ||||
| 	"github.com/quasoft/memstore" | ||||
| ) | ||||
| 
 | ||||
| func main() { | ||||
| 	// Create a memory store, providing authentication and | ||||
| 	// encryption key for securecookie | ||||
| 	store := memstore.NewMemStore( | ||||
| 		[]byte("authkey123"), | ||||
| 		[]byte("enckey12341234567890123456789012"), | ||||
| 	) | ||||
| 
 | ||||
| 	http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		// Get session by name. | ||||
| 		session, err := store.Get(r, "session1") | ||||
| 		if err != nil { | ||||
| 			log.Printf("Error retrieving session: %v", err) | ||||
| 		} | ||||
| 
 | ||||
| 		// The name should be 'foobar' if home page was visited before that and 'Guest' otherwise. | ||||
| 		user, ok := session.Values["username"] | ||||
| 		if !ok { | ||||
| 			user = "Guest" | ||||
| 		} | ||||
| 		fmt.Fprintf(w, "Hello %s", user) | ||||
| 	}) | ||||
| 
 | ||||
| 	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { | ||||
| 		// Get session by name. | ||||
| 		session, err := store.Get(r, "session1") | ||||
| 		if err != nil { | ||||
| 			log.Printf("Error retrieving session: %v", err) | ||||
| 		} | ||||
| 
 | ||||
| 		// Add values to the session object | ||||
| 		session.Values["username"] = "foobar" | ||||
| 		session.Values["email"] = "spam@eggs.com" | ||||
| 
 | ||||
| 		// Save values | ||||
| 		err = session.Save(r, w) | ||||
| 		if err != nil { | ||||
| 			log.Fatalf("Error saving session: %v", err) | ||||
| 		} | ||||
| 	}) | ||||
| 
 | ||||
| 	log.Printf("listening on http://%s/", "127.0.0.1:9090") | ||||
| 	log.Fatal(http.ListenAndServe("127.0.0.1:9090", nil)) | ||||
| } | ||||
| 
 | ||||
| ``` | ||||
							
								
								
									
										40
									
								
								vendor/github.com/quasoft/memstore/cache.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								vendor/github.com/quasoft/memstore/cache.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | |||
| package memstore | ||||
| 
 | ||||
| import ( | ||||
| 	"sync" | ||||
| ) | ||||
| 
 | ||||
| type cache struct { | ||||
| 	data  map[string]valueType | ||||
| 	mutex sync.RWMutex | ||||
| } | ||||
| 
 | ||||
| func newCache() *cache { | ||||
| 	return &cache{ | ||||
| 		data: make(map[string]valueType), | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (c *cache) value(name string) (valueType, bool) { | ||||
| 	c.mutex.RLock() | ||||
| 	defer c.mutex.RUnlock() | ||||
| 
 | ||||
| 	v, ok := c.data[name] | ||||
| 	return v, ok | ||||
| } | ||||
| 
 | ||||
| func (c *cache) setValue(name string, value valueType) { | ||||
| 	c.mutex.Lock() | ||||
| 	defer c.mutex.Unlock() | ||||
| 
 | ||||
| 	c.data[name] = value | ||||
| } | ||||
| 
 | ||||
| func (c *cache) delete(name string) { | ||||
| 	c.mutex.Lock() | ||||
| 	defer c.mutex.Unlock() | ||||
| 
 | ||||
| 	if _, ok := c.data[name]; ok { | ||||
| 		delete(c.data, name) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										155
									
								
								vendor/github.com/quasoft/memstore/memstore.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								vendor/github.com/quasoft/memstore/memstore.go
									
										
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,155 @@ | |||
| package memstore | ||||
| 
 | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/base32" | ||||
| 	"encoding/gob" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/gorilla/securecookie" | ||||
| 	"github.com/gorilla/sessions" | ||||
| ) | ||||
| 
 | ||||
| // MemStore is an in-memory implementation of gorilla/sessions, suitable | ||||
| // for use in tests and development environments. Do not use in production. | ||||
| // Values are cached in a map. The cache is protected and can be used by | ||||
| // multiple goroutines. | ||||
| type MemStore struct { | ||||
| 	Codecs  []securecookie.Codec | ||||
| 	Options *sessions.Options | ||||
| 	cache   *cache | ||||
| } | ||||
| 
 | ||||
| type valueType map[interface{}]interface{} | ||||
| 
 | ||||
| // NewMemStore returns a new MemStore. | ||||
| // | ||||
| // Keys are defined in pairs to allow key rotation, but the common case is | ||||
| // to set a single authentication key and optionally an encryption key. | ||||
| // | ||||
| // The first key in a pair is used for authentication and the second for | ||||
| // encryption. The encryption key can be set to nil or omitted in the last | ||||
| // pair, but the authentication key is required in all pairs. | ||||
| // | ||||
| // It is recommended to use an authentication key with 32 or 64 bytes. | ||||
| // The encryption key, if set, must be either 16, 24, or 32 bytes to select | ||||
| // AES-128, AES-192, or AES-256 modes. | ||||
| // | ||||
| // Use the convenience function securecookie.GenerateRandomKey() to create | ||||
| // strong keys. | ||||
| func NewMemStore(keyPairs ...[]byte) *MemStore { | ||||
| 	store := MemStore{ | ||||
| 		Codecs: securecookie.CodecsFromPairs(keyPairs...), | ||||
| 		Options: &sessions.Options{ | ||||
| 			Path:   "/", | ||||
| 			MaxAge: 86400 * 30, | ||||
| 		}, | ||||
| 		cache: newCache(), | ||||
| 	} | ||||
| 	store.MaxAge(store.Options.MaxAge) | ||||
| 	return &store | ||||
| } | ||||
| 
 | ||||
| // Get returns a session for the given name after adding it to the registry. | ||||
| // | ||||
| // It returns a new session if the sessions doesn't exist. Access IsNew on | ||||
| // the session to check if it is an existing session or a new one. | ||||
| // | ||||
| // It returns a new session and an error if the session exists but could | ||||
| // not be decoded. | ||||
| func (m *MemStore) Get(r *http.Request, name string) (*sessions.Session, error) { | ||||
| 	return sessions.GetRegistry(r).Get(m, name) | ||||
| } | ||||
| 
 | ||||
| // New returns a session for the given name without adding it to the registry. | ||||
| // | ||||
| // The difference between New() and Get() is that calling New() twice will | ||||
| // decode the session data twice, while Get() registers and reuses the same | ||||
| // decoded session after the first call. | ||||
| func (m *MemStore) New(r *http.Request, name string) (*sessions.Session, error) { | ||||
| 	session := sessions.NewSession(m, name) | ||||
| 	options := *m.Options | ||||
| 	session.Options = &options | ||||
| 	session.IsNew = true | ||||
| 
 | ||||
| 	c, err := r.Cookie(name) | ||||
| 	if err != nil { | ||||
| 		// Cookie not found, this is a new session | ||||
| 		return session, nil | ||||
| 	} | ||||
| 
 | ||||
| 	err = securecookie.DecodeMulti(name, c.Value, &session.ID, m.Codecs...) | ||||
| 	if err != nil { | ||||
| 		// Value could not be decrypted, consider this is a new session | ||||
| 		return session, err | ||||
| 	} | ||||
| 
 | ||||
| 	v, ok := m.cache.value(session.ID) | ||||
| 	if !ok { | ||||
| 		// No value found in cache, don't set any values in session object, | ||||
| 		// consider a new session | ||||
| 		return session, nil | ||||
| 	} | ||||
| 
 | ||||
| 	// Values found in session, this is not a new session | ||||
| 	session.Values = m.copy(v) | ||||
| 	session.IsNew = false | ||||
| 	return session, nil | ||||
| } | ||||
| 
 | ||||
| // Save adds a single session to the response. | ||||
| // Set Options.MaxAge to -1 or call MaxAge(-1) before saving the session to delete all values in it. | ||||
| func (m *MemStore) Save(r *http.Request, w http.ResponseWriter, s *sessions.Session) error { | ||||
| 	var cookieValue string | ||||
| 	if s.Options.MaxAge < 0 { | ||||
| 		cookieValue = "" | ||||
| 		m.cache.delete(s.ID) | ||||
| 		for k := range s.Values { | ||||
| 			delete(s.Values, k) | ||||
| 		} | ||||
| 	} else { | ||||
| 		if s.ID == "" { | ||||
| 			s.ID = strings.TrimRight(base32.StdEncoding.EncodeToString(securecookie.GenerateRandomKey(32)), "=") | ||||
| 		} | ||||
| 		encrypted, err := securecookie.EncodeMulti(s.Name(), s.ID, m.Codecs...) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		cookieValue = encrypted | ||||
| 		m.cache.setValue(s.ID, m.copy(s.Values)) | ||||
| 	} | ||||
| 	http.SetCookie(w, sessions.NewCookie(s.Name(), cookieValue, s.Options)) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| // MaxAge sets the maximum age for the store and the underlying cookie | ||||
| // implementation. Individual sessions can be deleted by setting Options.MaxAge | ||||
| // = -1 for that session. | ||||
| func (m *MemStore) MaxAge(age int) { | ||||
| 	m.Options.MaxAge = age | ||||
| 
 | ||||
| 	// Set the maxAge for each securecookie instance. | ||||
| 	for _, codec := range m.Codecs { | ||||
| 		if sc, ok := codec.(*securecookie.SecureCookie); ok { | ||||
| 			sc.MaxAge(age) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (m *MemStore) copy(v valueType) valueType { | ||||
| 	var buf bytes.Buffer | ||||
| 	enc := gob.NewEncoder(&buf) | ||||
| 	dec := gob.NewDecoder(&buf) | ||||
| 	err := enc.Encode(v) | ||||
| 	if err != nil { | ||||
| 		panic(fmt.Errorf("could not copy memstore value. Encoding to gob failed: %v", err)) | ||||
| 	} | ||||
| 	var value valueType | ||||
| 	err = dec.Decode(&value) | ||||
| 	if err != nil { | ||||
| 		panic(fmt.Errorf("could not copy memstore value. Decoding from gob failed: %v", err)) | ||||
| 	} | ||||
| 	return value | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue