diff options
Diffstat (limited to 'vendor/gitea.com')
18 files changed, 2390 insertions, 0 deletions
diff --git a/vendor/gitea.com/go-chi/session/.drone.yml b/vendor/gitea.com/go-chi/session/.drone.yml new file mode 100644 index 0000000000..d941e57505 --- /dev/null +++ b/vendor/gitea.com/go-chi/session/.drone.yml @@ -0,0 +1,37 @@ +--- +kind: pipeline +name: test + +platform: + os: linux + arch: amd64 + +clone: + disable: true + +workspace: + base: /go + path: src/session113 + +steps: +- name: git + pull: default + image: plugins/git:next + settings: + depth: 50 + tags: true + +- name: test + pull: default + image: golang:1.13 + environment: + GO111MODULE: on + GOPROXY: https://goproxy.cn + commands: + - go build -v + - go vet ./... + - go test -v -race -coverprofile=coverage.txt -covermode=atomic + when: + event: + - push + - pull_request
\ No newline at end of file diff --git a/vendor/gitea.com/go-chi/session/.gitignore b/vendor/gitea.com/go-chi/session/.gitignore new file mode 100644 index 0000000000..834722925c --- /dev/null +++ b/vendor/gitea.com/go-chi/session/.gitignore @@ -0,0 +1,4 @@ +ledis/tmp.db +nodb/tmp.db +/vendor +/.idea diff --git a/vendor/gitea.com/go-chi/session/LICENSE b/vendor/gitea.com/go-chi/session/LICENSE new file mode 100644 index 0000000000..8405e89a0b --- /dev/null +++ b/vendor/gitea.com/go-chi/session/LICENSE @@ -0,0 +1,191 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, "control" means (i) the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the +outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising +permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +"Object" form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +"submitted" means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of +this License; and +You must cause any modified files to carry prominent notices stating that You +changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets "[]" replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same "printed page" as the copyright notice for easier identification within +third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.
\ No newline at end of file diff --git a/vendor/gitea.com/go-chi/session/README.md b/vendor/gitea.com/go-chi/session/README.md new file mode 100644 index 0000000000..ed3258fcef --- /dev/null +++ b/vendor/gitea.com/go-chi/session/README.md @@ -0,0 +1,17 @@ +# Session + +Middleware session provides session management which copied from [Macaron Session](https://gitea.com/go-chi/session) for [go-chi](https://github.com/go-chi/chi). It can use many session providers, including memory, file, Redis, Memcache, PostgreSQL, MySQL, Couchbase, Ledis and Nodb. + +## Installation + +``` +go get gitea.com/go-chi/session +``` + +## Credits + +This package is a modified version of [go-macaron/session](github.com/go-macaron/session). + +## License + +This project is under the Apache License, Version 2.0. See the [LICENSE](LICENSE) file for the full license text.
\ No newline at end of file diff --git a/vendor/gitea.com/go-chi/session/couchbase/couchbase.go b/vendor/gitea.com/go-chi/session/couchbase/couchbase.go new file mode 100644 index 0000000000..31899a8574 --- /dev/null +++ b/vendor/gitea.com/go-chi/session/couchbase/couchbase.go @@ -0,0 +1,227 @@ +// Copyright 2013 Beego Authors +// Copyright 2014 The Macaron Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package session + +import ( + "strings" + "sync" + + "gitea.com/go-chi/session" + "github.com/couchbase/go-couchbase" +) + +// CouchbaseSessionStore represents a couchbase session store implementation. +type CouchbaseSessionStore struct { + b *couchbase.Bucket + sid string + lock sync.RWMutex + data map[interface{}]interface{} + maxlifetime int64 +} + +// Set sets value to given key in session. +func (s *CouchbaseSessionStore) Set(key, val interface{}) error { + s.lock.Lock() + defer s.lock.Unlock() + + s.data[key] = val + return nil +} + +// Get gets value by given key in session. +func (s *CouchbaseSessionStore) Get(key interface{}) interface{} { + s.lock.RLock() + defer s.lock.RUnlock() + + return s.data[key] +} + +// Delete delete a key from session. +func (s *CouchbaseSessionStore) Delete(key interface{}) error { + s.lock.Lock() + defer s.lock.Unlock() + + delete(s.data, key) + return nil +} + +// ID returns current session ID. +func (s *CouchbaseSessionStore) ID() string { + return s.sid +} + +// Release releases resource and save data to provider. +func (s *CouchbaseSessionStore) Release() error { + defer s.b.Close() + + // Skip encoding if the data is empty + if len(s.data) == 0 { + return nil + } + + data, err := session.EncodeGob(s.data) + if err != nil { + return err + } + + return s.b.Set(s.sid, int(s.maxlifetime), data) +} + +// Flush deletes all session data. +func (s *CouchbaseSessionStore) Flush() error { + s.lock.Lock() + defer s.lock.Unlock() + + s.data = make(map[interface{}]interface{}) + return nil +} + +// CouchbaseProvider represents a couchbase session provider implementation. +type CouchbaseProvider struct { + maxlifetime int64 + connStr string + pool string + bucket string + b *couchbase.Bucket +} + +func (cp *CouchbaseProvider) getBucket() *couchbase.Bucket { + c, err := couchbase.Connect(cp.connStr) + if err != nil { + return nil + } + + pool, err := c.GetPool(cp.pool) + if err != nil { + return nil + } + + bucket, err := pool.GetBucket(cp.bucket) + if err != nil { + return nil + } + + return bucket +} + +// Init initializes memory session provider. +// connStr is couchbase server REST/JSON URL +// e.g. http://host:port/, Pool, Bucket +func (p *CouchbaseProvider) Init(maxlifetime int64, connStr string) error { + p.maxlifetime = maxlifetime + configs := strings.Split(connStr, ",") + if len(configs) > 0 { + p.connStr = configs[0] + } + if len(configs) > 1 { + p.pool = configs[1] + } + if len(configs) > 2 { + p.bucket = configs[2] + } + + return nil +} + +// Read returns raw session store by session ID. +func (p *CouchbaseProvider) Read(sid string) (session.RawStore, error) { + p.b = p.getBucket() + + var doc []byte + + err := p.b.Get(sid, &doc) + var kv map[interface{}]interface{} + if doc == nil { + kv = make(map[interface{}]interface{}) + } else { + kv, err = session.DecodeGob(doc) + if err != nil { + return nil, err + } + } + + cs := &CouchbaseSessionStore{b: p.b, sid: sid, data: kv, maxlifetime: p.maxlifetime} + return cs, nil +} + +// Exist returns true if session with given ID exists. +func (p *CouchbaseProvider) Exist(sid string) bool { + p.b = p.getBucket() + defer p.b.Close() + + var doc []byte + + if err := p.b.Get(sid, &doc); err != nil || doc == nil { + return false + } else { + return true + } +} + +// Destroy deletes a session by session ID. +func (p *CouchbaseProvider) Destroy(sid string) error { + p.b = p.getBucket() + defer p.b.Close() + + p.b.Delete(sid) + return nil +} + +// Regenerate regenerates a session store from old session ID to new one. +func (p *CouchbaseProvider) Regenerate(oldsid, sid string) (session.RawStore, error) { + p.b = p.getBucket() + + var doc []byte + if err := p.b.Get(oldsid, &doc); err != nil || doc == nil { + p.b.Set(sid, int(p.maxlifetime), "") + } else { + err := p.b.Delete(oldsid) + if err != nil { + return nil, err + } + _, _ = p.b.Add(sid, int(p.maxlifetime), doc) + } + + err := p.b.Get(sid, &doc) + if err != nil { + return nil, err + } + var kv map[interface{}]interface{} + if doc == nil { + kv = make(map[interface{}]interface{}) + } else { + kv, err = session.DecodeGob(doc) + if err != nil { + return nil, err + } + } + + cs := &CouchbaseSessionStore{b: p.b, sid: sid, data: kv, maxlifetime: p.maxlifetime} + return cs, nil +} + +// Count counts and returns number of sessions. +func (p *CouchbaseProvider) Count() int { + // FIXME + return 0 +} + +// GC calls GC to clean expired sessions. +func (p *CouchbaseProvider) GC() {} + +func init() { + session.Register("couchbase", &CouchbaseProvider{}) +} diff --git a/vendor/gitea.com/go-chi/session/file.go b/vendor/gitea.com/go-chi/session/file.go new file mode 100644 index 0000000000..ce915344fb --- /dev/null +++ b/vendor/gitea.com/go-chi/session/file.go @@ -0,0 +1,274 @@ +// Copyright 2013 Beego Authors +// Copyright 2014 The Macaron Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package session + +import ( + "fmt" + "io/ioutil" + "log" + "os" + "path" + "path/filepath" + "sync" + "time" + + "github.com/unknwon/com" +) + +// FileStore represents a file session store implementation. +type FileStore struct { + p *FileProvider + sid string + lock sync.RWMutex + data map[interface{}]interface{} +} + +// NewFileStore creates and returns a file session store. +func NewFileStore(p *FileProvider, sid string, kv map[interface{}]interface{}) *FileStore { + return &FileStore{ + p: p, + sid: sid, + data: kv, + } +} + +// Set sets value to given key in session. +func (s *FileStore) Set(key, val interface{}) error { + s.lock.Lock() + defer s.lock.Unlock() + + s.data[key] = val + return nil +} + +// Get gets value by given key in session. +func (s *FileStore) Get(key interface{}) interface{} { + s.lock.RLock() + defer s.lock.RUnlock() + + return s.data[key] +} + +// Delete delete a key from session. +func (s *FileStore) Delete(key interface{}) error { + s.lock.Lock() + defer s.lock.Unlock() + + delete(s.data, key) + return nil +} + +// ID returns current session ID. +func (s *FileStore) ID() string { + return s.sid +} + +// Release releases resource and save data to provider. +func (s *FileStore) Release() error { + s.p.lock.Lock() + defer s.p.lock.Unlock() + + // Skip encoding if the data is empty + if len(s.data) == 0 { + return nil + } + + data, err := EncodeGob(s.data) + if err != nil { + return err + } + + return ioutil.WriteFile(s.p.filepath(s.sid), data, 0600) +} + +// Flush deletes all session data. +func (s *FileStore) Flush() error { + s.lock.Lock() + defer s.lock.Unlock() + + s.data = make(map[interface{}]interface{}) + return nil +} + +// FileProvider represents a file session provider implementation. +type FileProvider struct { + lock sync.RWMutex + maxlifetime int64 + rootPath string +} + +// Init initializes file session provider with given root path. +func (p *FileProvider) Init(maxlifetime int64, rootPath string) error { + p.lock.Lock() + p.maxlifetime = maxlifetime + p.rootPath = rootPath + p.lock.Unlock() + return nil +} + +func (p *FileProvider) filepath(sid string) string { + return path.Join(p.rootPath, string(sid[0]), string(sid[1]), sid) +} + +// Read returns raw session store by session ID. +func (p *FileProvider) Read(sid string) (_ RawStore, err error) { + filename := p.filepath(sid) + if err = os.MkdirAll(path.Dir(filename), 0700); err != nil { + return nil, err + } + p.lock.RLock() + defer p.lock.RUnlock() + + var f *os.File + ok := false + if com.IsFile(filename) { + modTime, err := com.FileMTime(filename) + if err != nil { + return nil, err + } + ok = (modTime + p.maxlifetime) >= time.Now().Unix() + } + if ok { + f, err = os.OpenFile(filename, os.O_RDONLY, 0600) + } else { + f, err = os.Create(filename) + } + if err != nil { + return nil, err + } + defer f.Close() + + if err = os.Chtimes(filename, time.Now(), time.Now()); err != nil { + return nil, err + } + + var kv map[interface{}]interface{} + data, err := ioutil.ReadAll(f) + if err != nil { + return nil, err + } + if len(data) == 0 { + kv = make(map[interface{}]interface{}) + } else { + kv, err = DecodeGob(data) + if err != nil { + return nil, err + } + } + return NewFileStore(p, sid, kv), nil +} + +// Exist returns true if session with given ID exists. +func (p *FileProvider) Exist(sid string) bool { + p.lock.RLock() + defer p.lock.RUnlock() + return com.IsFile(p.filepath(sid)) +} + +// Destroy deletes a session by session ID. +func (p *FileProvider) Destroy(sid string) error { + p.lock.Lock() + defer p.lock.Unlock() + return os.Remove(p.filepath(sid)) +} + +func (p *FileProvider) regenerate(oldsid, sid string) (err error) { + p.lock.Lock() + defer p.lock.Unlock() + + filename := p.filepath(sid) + if com.IsExist(filename) { + return fmt.Errorf("new sid '%s' already exists", sid) + } + + oldname := p.filepath(oldsid) + if !com.IsFile(oldname) { + data, err := EncodeGob(make(map[interface{}]interface{})) + if err != nil { + return err + } + if err = os.MkdirAll(path.Dir(oldname), 0700); err != nil { + return err + } + if err = ioutil.WriteFile(oldname, data, 0600); err != nil { + return err + } + } + + if err = os.MkdirAll(path.Dir(filename), 0700); err != nil { + return err + } + if err = os.Rename(oldname, filename); err != nil { + return err + } + return nil +} + +// Regenerate regenerates a session store from old session ID to new one. +func (p *FileProvider) Regenerate(oldsid, sid string) (_ RawStore, err error) { + if err := p.regenerate(oldsid, sid); err != nil { + return nil, err + } + + return p.Read(sid) +} + +// Count counts and returns number of sessions. +func (p *FileProvider) Count() int { + count := 0 + if err := filepath.Walk(p.rootPath, func(path string, fi os.FileInfo, err error) error { + if err != nil { + return err + } + + if !fi.IsDir() { + count++ + } + return nil + }); err != nil { + log.Printf("error counting session files: %v", err) + return 0 + } + return count +} + +// GC calls GC to clean expired sessions. +func (p *FileProvider) GC() { + p.lock.RLock() + defer p.lock.RUnlock() + + if !com.IsExist(p.rootPath) { + return + } + + if err := filepath.Walk(p.rootPath, func(path string, fi os.FileInfo, err error) error { + if err != nil { + return err + } + + if !fi.IsDir() && + (fi.ModTime().Unix()+p.maxlifetime) < time.Now().Unix() { + return os.Remove(path) + } + return nil + }); err != nil { + log.Printf("error garbage collecting session files: %v", err) + } +} + +func init() { + Register("file", &FileProvider{}) +} diff --git a/vendor/gitea.com/go-chi/session/go.mod b/vendor/gitea.com/go-chi/session/go.mod new file mode 100644 index 0000000000..6612080047 --- /dev/null +++ b/vendor/gitea.com/go-chi/session/go.mod @@ -0,0 +1,26 @@ +module gitea.com/go-chi/session + +go 1.11 + +require ( + github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 + github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89 + github.com/couchbase/gomemcached v0.1.1 // indirect + github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67 // indirect + github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 // indirect + github.com/edsrzf/mmap-go v1.0.0 // indirect + github.com/go-chi/chi v1.5.1 + github.com/go-redis/redis/v8 v8.4.0 + github.com/go-sql-driver/mysql v1.4.1 + github.com/lib/pq v1.2.0 + github.com/pelletier/go-toml v1.8.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 // indirect + github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92 + github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d // indirect + github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 + github.com/syndtr/goleveldb v1.0.0 // indirect + github.com/unknwon/com v1.0.1 + google.golang.org/appengine v1.6.7 // indirect + gopkg.in/ini.v1 v1.62.0 +) diff --git a/vendor/gitea.com/go-chi/session/go.sum b/vendor/gitea.com/go-chi/session/go.sum new file mode 100644 index 0000000000..e2c174b0c7 --- /dev/null +++ b/vendor/gitea.com/go-chi/session/go.sum @@ -0,0 +1,151 @@ +github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668 h1:U/lr3Dgy4WK+hNk4tyD+nuGjpVLPEHuJSFXMw11/HPA= +github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89 h1:uNLXQ6QO1TocD8BaN/KkRki0Xw0brCM1PKl/ZA5pgfs= +github.com/couchbase/go-couchbase v0.0.0-20201026062457-7b3be89bbd89/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A= +github.com/couchbase/gomemcached v0.1.1 h1:xCS8ZglJDhrlQg3jmK7Rn1V8f7bPjXABLC05CgLQauc= +github.com/couchbase/gomemcached v0.1.1/go.mod h1:mxliKQxOv84gQ0bJWbI+w9Wxdpt9HjDvgW9MjCym5Vo= +github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67 h1:NCqJ6fwen6YP0WlV/IyibaT0kPt3JEI1rA62V/UPKT4= +github.com/couchbase/goutils v0.0.0-20201030094643-5e82bb967e67/go.mod h1:BQwMFlJzDjFDG3DJUdU0KORxn88UlsOULuxLExMh3Hs= +github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76 h1:Lgdd/Qp96Qj8jqLpq2cI1I1X7BJnu06efS+XkhRoLUQ= +github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/go-chi/chi v1.5.1 h1:kfTK3Cxd/dkMu/rKs5ZceWYp+t5CtiE7vmaTv3LjC6w= +github.com/go-chi/chi v1.5.1/go.mod h1:REp24E+25iKvxgeTfHmdUoL5x15kBiDBlnIl5bCwe2k= +github.com/go-redis/redis/v8 v8.4.0 h1:J5NCReIgh3QgUJu398hUncxDExN4gMOHI11NVbVicGQ= +github.com/go-redis/redis/v8 v8.4.0/go.mod h1:A1tbYoHSa1fXwN+//ljcCYYJeLmVrwL9hbQN45Jdy0M= +github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3 h1:x95R7cp+rSeeqAMI2knLtQ0DKlaBhv2NrtrOvafPHRo= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e h1:JKmoR8x90Iww1ks85zJ1lfDGgIiMDuIptTOhJq+zKyg= +github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.2 h1:8mVmC9kjFFmA8H4pKMUhcblgifdkOIXPvbhN1T36q1M= +github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= +github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= +github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM= +github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 h1:xT+JlYxNGqyT+XcU8iUrN18JYed2TvG9yN5ULG2jATM= +github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= +github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92 h1:qvsJwGToa8rxb42cDRhkbKeX2H5N8BH+s2aUikGt8mI= +github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg= +github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d h1:NVwnfyR3rENtlz62bcrkXME3INVUa4lcdGt+opvxExs= +github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304 h1:Jpy1PXuP99tXNrhbq2BaPz9B+jNAvH1JPQQpG/9GCXY= +github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= +github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= +github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs= +github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM= +go.opentelemetry.io/otel v0.14.0 h1:YFBEfjCk9MTjaytCNSUkp9Q8lF7QJezA06T71FbQxLQ= +go.opentelemetry.io/otel v0.14.0/go.mod h1:vH5xEuwy7Rts0GNtsCW3HYQoZDY+OmBJ6t1bFGGlxgw= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0 h1:wBouT66WTYFXdxfVdz9sVWARVd/2vfGcmI45D2gj45M= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU= +gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/vendor/gitea.com/go-chi/session/memcache/memcache.go b/vendor/gitea.com/go-chi/session/memcache/memcache.go new file mode 100644 index 0000000000..ed08b915df --- /dev/null +++ b/vendor/gitea.com/go-chi/session/memcache/memcache.go @@ -0,0 +1,203 @@ +// Copyright 2013 Beego Authors +// Copyright 2014 The Macaron Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package session + +import ( + "fmt" + "strings" + "sync" + + "gitea.com/go-chi/session" + "github.com/bradfitz/gomemcache/memcache" +) + +// MemcacheStore represents a memcache session store implementation. +type MemcacheStore struct { + c *memcache.Client + sid string + expire int32 + lock sync.RWMutex + data map[interface{}]interface{} +} + +// NewMemcacheStore creates and returns a memcache session store. +func NewMemcacheStore(c *memcache.Client, sid string, expire int32, kv map[interface{}]interface{}) *MemcacheStore { + return &MemcacheStore{ + c: c, + sid: sid, + expire: expire, + data: kv, + } +} + +func NewItem(sid string, data []byte, expire int32) *memcache.Item { + return &memcache.Item{ + Key: sid, + Value: data, + Expiration: expire, + } +} + +// Set sets value to given key in session. +func (s *MemcacheStore) Set(key, val interface{}) error { + s.lock.Lock() + defer s.lock.Unlock() + + s.data[key] = val + return nil +} + +// Get gets value by given key in session. +func (s *MemcacheStore) Get(key interface{}) interface{} { + s.lock.RLock() + defer s.lock.RUnlock() + + return s.data[key] +} + +// Delete delete a key from session. +func (s *MemcacheStore) Delete(key interface{}) error { + s.lock.Lock() + defer s.lock.Unlock() + + delete(s.data, key) + return nil +} + +// ID returns current session ID. +func (s *MemcacheStore) ID() string { + return s.sid +} + +// Release releases resource and save data to provider. +func (s *MemcacheStore) Release() error { + // Skip encoding if the data is empty + if len(s.data) == 0 { + return nil + } + + data, err := session.EncodeGob(s.data) + if err != nil { + return err + } + + return s.c.Set(NewItem(s.sid, data, s.expire)) +} + +// Flush deletes all session data. +func (s *MemcacheStore) Flush() error { + s.lock.Lock() + defer s.lock.Unlock() + + s.data = make(map[interface{}]interface{}) + return nil +} + +// MemcacheProvider represents a memcache session provider implementation. +type MemcacheProvider struct { + c *memcache.Client + expire int32 +} + +// Init initializes memcache session provider. +// connStrs: 127.0.0.1:9090;127.0.0.1:9091 +func (p *MemcacheProvider) Init(expire int64, connStrs string) error { + p.expire = int32(expire) + p.c = memcache.New(strings.Split(connStrs, ";")...) + return nil +} + +// Read returns raw session store by session ID. +func (p *MemcacheProvider) Read(sid string) (session.RawStore, error) { + if !p.Exist(sid) { + if err := p.c.Set(NewItem(sid, []byte(""), p.expire)); err != nil { + return nil, err + } + } + + var kv map[interface{}]interface{} + item, err := p.c.Get(sid) + if err != nil { + return nil, err + } + if len(item.Value) == 0 { + kv = make(map[interface{}]interface{}) + } else { + kv, err = session.DecodeGob(item.Value) + if err != nil { + return nil, err + } + } + + return NewMemcacheStore(p.c, sid, p.expire, kv), nil +} + +// Exist returns true if session with given ID exists. +func (p *MemcacheProvider) Exist(sid string) bool { + _, err := p.c.Get(sid) + return err == nil +} + +// Destroy deletes a session by session ID. +func (p *MemcacheProvider) Destroy(sid string) error { + return p.c.Delete(sid) +} + +// Regenerate regenerates a session store from old session ID to new one. +func (p *MemcacheProvider) Regenerate(oldsid, sid string) (_ session.RawStore, err error) { + if p.Exist(sid) { + return nil, fmt.Errorf("new sid '%s' already exists", sid) + } + + item := NewItem(sid, []byte(""), p.expire) + if p.Exist(oldsid) { + item, err = p.c.Get(oldsid) + if err != nil { + return nil, err + } else if err = p.c.Delete(oldsid); err != nil { + return nil, err + } + item.Key = sid + } + if err = p.c.Set(item); err != nil { + return nil, err + } + + var kv map[interface{}]interface{} + if len(item.Value) == 0 { + kv = make(map[interface{}]interface{}) + } else { + kv, err = session.DecodeGob(item.Value) + if err != nil { + return nil, err + } + } + + return NewMemcacheStore(p.c, sid, p.expire, kv), nil +} + +// Count counts and returns number of sessions. +func (p *MemcacheProvider) Count() int { + // FIXME: how come this library does not have Stats method? + return -1 +} + +// GC calls GC to clean expired sessions. +func (p *MemcacheProvider) GC() {} + +func init() { + session.Register("memcache", &MemcacheProvider{}) +} diff --git a/vendor/gitea.com/go-chi/session/memcache/memcache.goconvey b/vendor/gitea.com/go-chi/session/memcache/memcache.goconvey new file mode 100644 index 0000000000..8485e986e4 --- /dev/null +++ b/vendor/gitea.com/go-chi/session/memcache/memcache.goconvey @@ -0,0 +1 @@ +ignore
\ No newline at end of file diff --git a/vendor/gitea.com/go-chi/session/memory.go b/vendor/gitea.com/go-chi/session/memory.go new file mode 100644 index 0000000000..d3a623c672 --- /dev/null +++ b/vendor/gitea.com/go-chi/session/memory.go @@ -0,0 +1,223 @@ +// Copyright 2013 Beego Authors
+// Copyright 2014 The Macaron Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License"): you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package session
+
+import (
+ "container/list"
+ "fmt"
+ "sync"
+ "time"
+)
+
+// MemStore represents a in-memory session store implementation.
+type MemStore struct {
+ sid string
+ lock sync.RWMutex
+ data map[interface{}]interface{}
+ lastAccess time.Time
+}
+
+// NewMemStore creates and returns a memory session store.
+func NewMemStore(sid string) *MemStore {
+ return &MemStore{
+ sid: sid,
+ data: make(map[interface{}]interface{}),
+ lastAccess: time.Now(),
+ }
+}
+
+// Set sets value to given key in session.
+func (s *MemStore) Set(key, val interface{}) error {
+ s.lock.Lock()
+ defer s.lock.Unlock()
+
+ s.data[key] = val
+ return nil
+}
+
+// Get gets value by given key in session.
+func (s *MemStore) Get(key interface{}) interface{} {
+ s.lock.RLock()
+ defer s.lock.RUnlock()
+
+ return s.data[key]
+}
+
+// Delete deletes a key from session.
+func (s *MemStore) Delete(key interface{}) error {
+ s.lock.Lock()
+ defer s.lock.Unlock()
+
+ delete(s.data, key)
+ return nil
+}
+
+// ID returns current session ID.
+func (s *MemStore) ID() string {
+ return s.sid
+}
+
+// Release releases resource and save data to provider.
+func (*MemStore) Release() error {
+ return nil
+}
+
+// Flush deletes all session data.
+func (s *MemStore) Flush() error {
+ s.lock.Lock()
+ defer s.lock.Unlock()
+
+ s.data = make(map[interface{}]interface{})
+ return nil
+}
+
+// MemProvider represents a in-memory session provider implementation.
+type MemProvider struct {
+ lock sync.RWMutex
+ maxLifetime int64
+ data map[string]*list.Element
+ // A priority list whose lastAccess newer gets higer priority.
+ list *list.List
+}
+
+// Init initializes memory session provider.
+func (p *MemProvider) Init(maxLifetime int64, _ string) error {
+ p.lock.Lock()
+ p.list = list.New()
+ p.data = make(map[string]*list.Element)
+ p.maxLifetime = maxLifetime
+ p.lock.Unlock()
+ return nil
+}
+
+// update expands time of session store by given ID.
+func (p *MemProvider) update(sid string) error {
+ p.lock.Lock()
+ defer p.lock.Unlock()
+
+ if e, ok := p.data[sid]; ok {
+ e.Value.(*MemStore).lastAccess = time.Now()
+ p.list.MoveToFront(e)
+ return nil
+ }
+ return nil
+}
+
+// Read returns raw session store by session ID.
+func (p *MemProvider) Read(sid string) (_ RawStore, err error) {
+ p.lock.RLock()
+ e, ok := p.data[sid]
+ p.lock.RUnlock()
+
+ // Only restore if the session is still alive.
+ if ok && (e.Value.(*MemStore).lastAccess.Unix()+p.maxLifetime) >= time.Now().Unix() {
+ if err = p.update(sid); err != nil {
+ return nil, err
+ }
+ return e.Value.(*MemStore), nil
+ }
+
+ // Create a new session.
+ p.lock.Lock()
+ defer p.lock.Unlock()
+ if ok {
+ p.list.Remove(e)
+ delete(p.data, sid)
+ }
+ s := NewMemStore(sid)
+ p.data[sid] = p.list.PushBack(s)
+ return s, nil
+}
+
+// Exist returns true if session with given ID exists.
+func (p *MemProvider) Exist(sid string) bool {
+ p.lock.RLock()
+ defer p.lock.RUnlock()
+
+ _, ok := p.data[sid]
+ return ok
+}
+
+// Destroy deletes a session by session ID.
+func (p *MemProvider) Destroy(sid string) error {
+ p.lock.Lock()
+ defer p.lock.Unlock()
+
+ e, ok := p.data[sid]
+ if !ok {
+ return nil
+ }
+
+ p.list.Remove(e)
+ delete(p.data, sid)
+ return nil
+}
+
+// Regenerate regenerates a session store from old session ID to new one.
+func (p *MemProvider) Regenerate(oldsid, sid string) (RawStore, error) {
+ if p.Exist(sid) {
+ return nil, fmt.Errorf("new sid '%s' already exists", sid)
+ }
+
+ s, err := p.Read(oldsid)
+ if err != nil {
+ return nil, err
+ }
+
+ if err = p.Destroy(oldsid); err != nil {
+ return nil, err
+ }
+
+ s.(*MemStore).sid = sid
+
+ p.lock.Lock()
+ defer p.lock.Unlock()
+ p.data[sid] = p.list.PushBack(s)
+ return s, nil
+}
+
+// Count counts and returns number of sessions.
+func (p *MemProvider) Count() int {
+ return p.list.Len()
+}
+
+// GC calls GC to clean expired sessions.
+func (p *MemProvider) GC() {
+ p.lock.RLock()
+ for {
+ // No session in the list.
+ e := p.list.Back()
+ if e == nil {
+ break
+ }
+
+ if (e.Value.(*MemStore).lastAccess.Unix() + p.maxLifetime) < time.Now().Unix() {
+ p.lock.RUnlock()
+ p.lock.Lock()
+ p.list.Remove(e)
+ delete(p.data, e.Value.(*MemStore).sid)
+ p.lock.Unlock()
+ p.lock.RLock()
+ } else {
+ break
+ }
+ }
+ p.lock.RUnlock()
+}
+
+func init() {
+ Register("memory", &MemProvider{})
+}
diff --git a/vendor/gitea.com/go-chi/session/mysql/mysql.go b/vendor/gitea.com/go-chi/session/mysql/mysql.go new file mode 100644 index 0000000000..7ec647bf3a --- /dev/null +++ b/vendor/gitea.com/go-chi/session/mysql/mysql.go @@ -0,0 +1,201 @@ +// Copyright 2013 Beego Authors +// Copyright 2014 The Macaron Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package session + +import ( + "database/sql" + "fmt" + "log" + "sync" + "time" + + "gitea.com/go-chi/session" + _ "github.com/go-sql-driver/mysql" +) + +// MysqlStore represents a mysql session store implementation. +type MysqlStore struct { + c *sql.DB + sid string + lock sync.RWMutex + data map[interface{}]interface{} +} + +// NewMysqlStore creates and returns a mysql session store. +func NewMysqlStore(c *sql.DB, sid string, kv map[interface{}]interface{}) *MysqlStore { + return &MysqlStore{ + c: c, + sid: sid, + data: kv, + } +} + +// Set sets value to given key in session. +func (s *MysqlStore) Set(key, val interface{}) error { + s.lock.Lock() + defer s.lock.Unlock() + + s.data[key] = val + return nil +} + +// Get gets value by given key in session. +func (s *MysqlStore) Get(key interface{}) interface{} { + s.lock.RLock() + defer s.lock.RUnlock() + + return s.data[key] +} + +// Delete delete a key from session. +func (s *MysqlStore) Delete(key interface{}) error { + s.lock.Lock() + defer s.lock.Unlock() + + delete(s.data, key) + return nil +} + +// ID returns current session ID. +func (s *MysqlStore) ID() string { + return s.sid +} + +// Release releases resource and save data to provider. +func (s *MysqlStore) Release() error { + // Skip encoding if the data is empty + if len(s.data) == 0 { + return nil + } + + data, err := session.EncodeGob(s.data) + if err != nil { + return err + } + + _, err = s.c.Exec("UPDATE session SET data=?, expiry=? WHERE `key`=?", + data, time.Now().Unix(), s.sid) + return err +} + +// Flush deletes all session data. +func (s *MysqlStore) Flush() error { + s.lock.Lock() + defer s.lock.Unlock() + + s.data = make(map[interface{}]interface{}) + return nil +} + +// MysqlProvider represents a mysql session provider implementation. +type MysqlProvider struct { + c *sql.DB + expire int64 +} + +// Init initializes mysql session provider. +// connStr: username:password@protocol(address)/dbname?param=value +func (p *MysqlProvider) Init(expire int64, connStr string) (err error) { + p.expire = expire + + p.c, err = sql.Open("mysql", connStr) + if err != nil { + return err + } + return p.c.Ping() +} + +// Read returns raw session store by session ID. +func (p *MysqlProvider) Read(sid string) (session.RawStore, error) { + now := time.Now().Unix() + var data []byte + expiry := now + err := p.c.QueryRow("SELECT data, expiry FROM session WHERE `key`=?", sid).Scan(&data, &expiry) + if err == sql.ErrNoRows { + _, err = p.c.Exec("INSERT INTO session(`key`,data,expiry) VALUES(?,?,?)", + sid, "", now) + } + if err != nil { + return nil, err + } + + var kv map[interface{}]interface{} + if len(data) == 0 || expiry+p.expire <= now { + kv = make(map[interface{}]interface{}) + } else { + kv, err = session.DecodeGob(data) + if err != nil { + return nil, err + } + } + + return NewMysqlStore(p.c, sid, kv), nil +} + +// Exist returns true if session with given ID exists. +func (p *MysqlProvider) Exist(sid string) bool { + var data []byte + err := p.c.QueryRow("SELECT data FROM session WHERE `key`=?", sid).Scan(&data) + if err != nil && err != sql.ErrNoRows { + panic("session/mysql: error checking existence: " + err.Error()) + } + return err != sql.ErrNoRows +} + +// Destroy deletes a session by session ID. +func (p *MysqlProvider) Destroy(sid string) error { + _, err := p.c.Exec("DELETE FROM session WHERE `key`=?", sid) + return err +} + +// Regenerate regenerates a session store from old session ID to new one. +func (p *MysqlProvider) Regenerate(oldsid, sid string) (_ session.RawStore, err error) { + if p.Exist(sid) { + return nil, fmt.Errorf("new sid '%s' already exists", sid) + } + + if !p.Exist(oldsid) { + if _, err = p.c.Exec("INSERT INTO session(`key`,data,expiry) VALUES(?,?,?)", + oldsid, "", time.Now().Unix()); err != nil { + return nil, err + } + } + + if _, err = p.c.Exec("UPDATE session SET `key`=? WHERE `key`=?", sid, oldsid); err != nil { + return nil, err + } + + return p.Read(sid) +} + +// Count counts and returns number of sessions. +func (p *MysqlProvider) Count() (total int) { + if err := p.c.QueryRow("SELECT COUNT(*) AS NUM FROM session").Scan(&total); err != nil { + panic("session/mysql: error counting records: " + err.Error()) + } + return total +} + +// GC calls GC to clean expired sessions. +func (p *MysqlProvider) GC() { + if _, err := p.c.Exec("DELETE FROM session WHERE expiry + ? <= UNIX_TIMESTAMP(NOW())", p.expire); err != nil { + log.Printf("session/mysql: error garbage collecting: %v", err) + } +} + +func init() { + session.Register("mysql", &MysqlProvider{}) +} diff --git a/vendor/gitea.com/go-chi/session/mysql/mysql.goconvey b/vendor/gitea.com/go-chi/session/mysql/mysql.goconvey new file mode 100644 index 0000000000..8485e986e4 --- /dev/null +++ b/vendor/gitea.com/go-chi/session/mysql/mysql.goconvey @@ -0,0 +1 @@ +ignore
\ No newline at end of file diff --git a/vendor/gitea.com/go-chi/session/postgres/postgres.go b/vendor/gitea.com/go-chi/session/postgres/postgres.go new file mode 100644 index 0000000000..383906d8d7 --- /dev/null +++ b/vendor/gitea.com/go-chi/session/postgres/postgres.go @@ -0,0 +1,202 @@ +// Copyright 2013 Beego Authors +// Copyright 2014 The Macaron Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package session + +import ( + "database/sql" + "fmt" + "log" + "sync" + "time" + + "gitea.com/go-chi/session" + _ "github.com/lib/pq" +) + +// PostgresStore represents a postgres session store implementation. +type PostgresStore struct { + c *sql.DB + sid string + lock sync.RWMutex + data map[interface{}]interface{} +} + +// NewPostgresStore creates and returns a postgres session store. +func NewPostgresStore(c *sql.DB, sid string, kv map[interface{}]interface{}) *PostgresStore { + return &PostgresStore{ + c: c, + sid: sid, + data: kv, + } +} + +// Set sets value to given key in session. +func (s *PostgresStore) Set(key, value interface{}) error { + s.lock.Lock() + defer s.lock.Unlock() + + s.data[key] = value + return nil +} + +// Get gets value by given key in session. +func (s *PostgresStore) Get(key interface{}) interface{} { + s.lock.RLock() + defer s.lock.RUnlock() + + return s.data[key] +} + +// Delete delete a key from session. +func (s *PostgresStore) Delete(key interface{}) error { + s.lock.Lock() + defer s.lock.Unlock() + + delete(s.data, key) + return nil +} + +// ID returns current session ID. +func (s *PostgresStore) ID() string { + return s.sid +} + +// save postgres session values to database. +// must call this method to save values to database. +func (s *PostgresStore) Release() error { + // Skip encoding if the data is empty + if len(s.data) == 0 { + return nil + } + + data, err := session.EncodeGob(s.data) + if err != nil { + return err + } + + _, err = s.c.Exec("UPDATE session SET data=$1, expiry=$2 WHERE key=$3", + data, time.Now().Unix(), s.sid) + return err +} + +// Flush deletes all session data. +func (s *PostgresStore) Flush() error { + s.lock.Lock() + defer s.lock.Unlock() + + s.data = make(map[interface{}]interface{}) + return nil +} + +// PostgresProvider represents a postgres session provider implementation. +type PostgresProvider struct { + c *sql.DB + maxlifetime int64 +} + +// Init initializes postgres session provider. +// connStr: user=a password=b host=localhost port=5432 dbname=c sslmode=disable +func (p *PostgresProvider) Init(maxlifetime int64, connStr string) (err error) { + p.maxlifetime = maxlifetime + + p.c, err = sql.Open("postgres", connStr) + if err != nil { + return err + } + return p.c.Ping() +} + +// Read returns raw session store by session ID. +func (p *PostgresProvider) Read(sid string) (session.RawStore, error) { + now := time.Now().Unix() + var data []byte + expiry := now + err := p.c.QueryRow("SELECT data, expiry FROM session WHERE key=$1", sid).Scan(&data, &expiry) + if err == sql.ErrNoRows { + _, err = p.c.Exec("INSERT INTO session(key,data,expiry) VALUES($1,$2,$3)", + sid, "", now) + } + if err != nil { + return nil, err + } + + var kv map[interface{}]interface{} + if len(data) == 0 || expiry+p.maxlifetime <= now { + kv = make(map[interface{}]interface{}) + } else { + kv, err = session.DecodeGob(data) + if err != nil { + return nil, err + } + } + + return NewPostgresStore(p.c, sid, kv), nil +} + +// Exist returns true if session with given ID exists. +func (p *PostgresProvider) Exist(sid string) bool { + var data []byte + err := p.c.QueryRow("SELECT data FROM session WHERE key=$1", sid).Scan(&data) + if err != nil && err != sql.ErrNoRows { + panic("session/postgres: error checking existence: " + err.Error()) + } + return err != sql.ErrNoRows +} + +// Destroy deletes a session by session ID. +func (p *PostgresProvider) Destroy(sid string) error { + _, err := p.c.Exec("DELETE FROM session WHERE key=$1", sid) + return err +} + +// Regenerate regenerates a session store from old session ID to new one. +func (p *PostgresProvider) Regenerate(oldsid, sid string) (_ session.RawStore, err error) { + if p.Exist(sid) { + return nil, fmt.Errorf("new sid '%s' already exists", sid) + } + + if !p.Exist(oldsid) { + if _, err = p.c.Exec("INSERT INTO session(key,data,expiry) VALUES($1,$2,$3)", + oldsid, "", time.Now().Unix()); err != nil { + return nil, err + } + } + + if _, err = p.c.Exec("UPDATE session SET key=$1 WHERE key=$2", sid, oldsid); err != nil { + return nil, err + } + + return p.Read(sid) +} + +// Count counts and returns number of sessions. +func (p *PostgresProvider) Count() (total int) { + if err := p.c.QueryRow("SELECT COUNT(*) AS NUM FROM session").Scan(&total); err != nil { + panic("session/postgres: error counting records: " + err.Error()) + } + return total +} + +// GC calls GC to clean expired sessions. +func (p *PostgresProvider) GC() { + if _, err := p.c.Exec("DELETE FROM session WHERE EXTRACT(EPOCH FROM NOW()) - expiry > $1", p.maxlifetime); err != nil { + log.Printf("session/postgres: error garbage collecting: %v", err) + } +} + +func init() { + session.Register("postgres", &PostgresProvider{}) +} diff --git a/vendor/gitea.com/go-chi/session/postgres/postgres.goconvey b/vendor/gitea.com/go-chi/session/postgres/postgres.goconvey new file mode 100644 index 0000000000..8485e986e4 --- /dev/null +++ b/vendor/gitea.com/go-chi/session/postgres/postgres.goconvey @@ -0,0 +1 @@ +ignore
\ No newline at end of file diff --git a/vendor/gitea.com/go-chi/session/secret.go b/vendor/gitea.com/go-chi/session/secret.go new file mode 100644 index 0000000000..e56a50615b --- /dev/null +++ b/vendor/gitea.com/go-chi/session/secret.go @@ -0,0 +1,100 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package session + +import ( + "crypto/aes" + "crypto/cipher" + "crypto/rand" + "crypto/sha256" + "encoding/base64" + "errors" + "io" +) + +// NewSecret creates a new secret +func NewSecret() (string, error) { + return NewSecretWithLength(32) +} + +// NewSecretWithLength creates a new secret for a given length +func NewSecretWithLength(length int64) (string, error) { + return randomString(length) +} + +func randomBytes(len int64) ([]byte, error) { + b := make([]byte, len) + if _, err := rand.Read(b); err != nil { + return nil, err + } + return b, nil +} + +func randomString(len int64) (string, error) { + b, err := randomBytes(len) + return base64.URLEncoding.EncodeToString(b), err +} + +// AesEncrypt encrypts text and given key with AES. +func AesEncrypt(key, text []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + b := base64.StdEncoding.EncodeToString(text) + ciphertext := make([]byte, aes.BlockSize+len(b)) + iv := ciphertext[:aes.BlockSize] + if _, err := io.ReadFull(rand.Reader, iv); err != nil { + return nil, err + } + cfb := cipher.NewCFBEncrypter(block, iv) + cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b)) + return ciphertext, nil +} + +// AesDecrypt decrypts text and given key with AES. +func AesDecrypt(key, text []byte) ([]byte, error) { + block, err := aes.NewCipher(key) + if err != nil { + return nil, err + } + if len(text) < aes.BlockSize { + return nil, errors.New("ciphertext too short") + } + iv := text[:aes.BlockSize] + text = text[aes.BlockSize:] + cfb := cipher.NewCFBDecrypter(block, iv) + cfb.XORKeyStream(text, text) + data, err := base64.StdEncoding.DecodeString(string(text)) + if err != nil { + return nil, err + } + return data, nil +} + +// EncryptSecret encrypts a string with given key into a hex string +func EncryptSecret(key string, str string) (string, error) { + keyHash := sha256.Sum256([]byte(key)) + plaintext := []byte(str) + ciphertext, err := AesEncrypt(keyHash[:], plaintext) + if err != nil { + return "", err + } + return base64.StdEncoding.EncodeToString(ciphertext), nil +} + +// DecryptSecret decrypts a previously encrypted hex string +func DecryptSecret(key string, cipherhex string) (string, error) { + keyHash := sha256.Sum256([]byte(key)) + ciphertext, err := base64.StdEncoding.DecodeString(cipherhex) + if err != nil { + return "", err + } + plaintext, err := AesDecrypt(keyHash[:], ciphertext) + if err != nil { + return "", err + } + return string(plaintext), nil +} diff --git a/vendor/gitea.com/go-chi/session/session.go b/vendor/gitea.com/go-chi/session/session.go new file mode 100644 index 0000000000..97eb5ad365 --- /dev/null +++ b/vendor/gitea.com/go-chi/session/session.go @@ -0,0 +1,466 @@ +// Copyright 2013 Beego Authors +// Copyright 2014 The Macaron Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +// Package session a middleware that provides the session management of Macaron. +package session + +import ( + "context" + "encoding/hex" + "errors" + "fmt" + "net/http" + "net/url" + "time" +) + +const version = "0.7.0" + +// Version returns the version +func Version() string { + return version +} + +// RawStore is the interface that operates the session data. +type RawStore interface { + // Set sets value to given key in session. + Set(interface{}, interface{}) error + // Get gets value by given key in session. + Get(interface{}) interface{} + // Delete deletes a key from session. + Delete(interface{}) error + // ID returns current session ID. + ID() string + // Release releases session resource and save data to provider. + Release() error + // Flush deletes all session data. + Flush() error +} + +// Store is the interface that contains all data for one session process with specific ID. +type Store interface { + RawStore + // Read returns raw session store by session ID. + Read(string) (RawStore, error) + // Destroy deletes a session. + Destroy(http.ResponseWriter, *http.Request) error + // RegenerateID regenerates a session store from old session ID to new one. + RegenerateID(http.ResponseWriter, *http.Request) (RawStore, error) + // Count counts and returns number of sessions. + Count() int + // GC calls GC to clean expired sessions. + GC() +} + +type store struct { + RawStore + *Manager +} + +var _ Store = &store{} + +// Options represents a struct for specifying configuration options for the session middleware. +type Options struct { + // Name of provider. Default is "memory". + Provider string + // Provider configuration, it's corresponding to provider. + ProviderConfig string + // Cookie name to save session ID. Default is "MacaronSession". + CookieName string + // Cookie path to store. Default is "/". + CookiePath string + // GC interval time in seconds. Default is 3600. + Gclifetime int64 + // Max life time in seconds. Default is whatever GC interval time is. + Maxlifetime int64 + // Use HTTPS only. Default is false. + Secure bool + // Cookie life time. Default is 0. + CookieLifeTime int + // SameSite set the cookie SameSite + SameSite http.SameSite + // Cookie domain name. Default is empty. + Domain string + // Session ID length. Default is 16. + IDLength int + // Ignore release for websocket. Default is false. + IgnoreReleaseForWebSocket bool + // FlashEncryptionKey sets the encryption key for flash messages + FlashEncryptionKey string +} + +func prepareOptions(options []Options) Options { + var opt Options + if len(options) > 0 { + opt = options[0] + } + + if len(opt.Provider) == 0 { + opt.Provider = "memory" + } + if len(opt.ProviderConfig) == 0 { + opt.ProviderConfig = "data/sessions" + } + if len(opt.CookieName) == 0 { + opt.CookieName = "MacaronSession" + } + if len(opt.CookiePath) == 0 { + opt.CookiePath = "/" + } + if opt.Gclifetime == 0 { + opt.Gclifetime = 3600 + } + if opt.Maxlifetime == 0 { + opt.Maxlifetime = opt.Gclifetime + } + if !opt.Secure { + opt.Secure = false + } + if opt.IDLength == 0 { + opt.IDLength = 16 + } + if len(opt.FlashEncryptionKey) == 0 { + opt.FlashEncryptionKey = "" + } + if len(opt.FlashEncryptionKey) == 0 { + opt.FlashEncryptionKey, _ = NewSecret() + } + + return opt +} + +// GetCookie returns given cookie value from request header. +func GetCookie(req *http.Request, name string) string { + cookie, err := req.Cookie(name) + if err != nil { + return "" + } + val, _ := url.QueryUnescape(cookie.Value) + return val +} + +// NewCookie creates cookie via given params and value. +// FIXME: IE support? http://golanghome.com/post/620#reply2 +func NewCookie(name string, value string, others ...interface{}) *http.Cookie { + cookie := http.Cookie{} + cookie.Name = name + cookie.Value = url.QueryEscape(value) + + if len(others) > 0 { + switch v := others[0].(type) { + case int: + cookie.MaxAge = v + case int64: + cookie.MaxAge = int(v) + case int32: + cookie.MaxAge = int(v) + case func(*http.Cookie): + v(&cookie) + } + } + + cookie.Path = "/" + if len(others) > 1 { + if v, ok := others[1].(string); ok && len(v) > 0 { + cookie.Path = v + } else if v, ok := others[1].(func(*http.Cookie)); ok { + v(&cookie) + } + } + + if len(others) > 2 { + if v, ok := others[2].(string); ok && len(v) > 0 { + cookie.Domain = v + } else if v, ok := others[1].(func(*http.Cookie)); ok { + v(&cookie) + } + } + + if len(others) > 3 { + switch v := others[3].(type) { + case bool: + cookie.Secure = v + case func(*http.Cookie): + v(&cookie) + default: + if others[3] != nil { + cookie.Secure = true + } + } + } + + if len(others) > 4 { + if v, ok := others[4].(bool); ok && v { + cookie.HttpOnly = true + } else if v, ok := others[1].(func(*http.Cookie)); ok { + v(&cookie) + } + } + + if len(others) > 5 { + if v, ok := others[5].(time.Time); ok { + cookie.Expires = v + cookie.RawExpires = v.Format(time.UnixDate) + } else if v, ok := others[1].(func(*http.Cookie)); ok { + v(&cookie) + } + } + + if len(others) > 6 { + for _, other := range others[6:] { + if v, ok := other.(func(*http.Cookie)); ok { + v(&cookie) + } + } + } + return &cookie +} + +// Sessioner is a middleware that maps a session.SessionStore service into the Macaron handler chain. +// An single variadic session.Options struct can be optionally provided to configure. +func Sessioner(options ...Options) func(next http.Handler) http.Handler { + opt := prepareOptions(options) + manager, err := NewManager(opt.Provider, opt) + if err != nil { + panic(err) + } + go manager.startGC() + + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + sess, err := manager.Start(w, req) + if err != nil { + panic("session(start): " + err.Error()) + } + + var s = store{ + RawStore: sess, + Manager: manager, + } + + req = req.WithContext(context.WithValue(req.Context(), interface{}("Session"), &s)) + + next.ServeHTTP(w, req) + + if manager.opt.IgnoreReleaseForWebSocket && req.Header.Get("Upgrade") == "websocket" { + return + } + + if err = sess.Release(); err != nil { + panic("session(release): " + err.Error()) + } + }) + } +} + +// GetSession returns session store +func GetSession(req *http.Request) Store { + sessCtx := req.Context().Value("Session") + sess, _ := sessCtx.(*store) + return sess +} + +// Provider is the interface that provides session manipulations. +type Provider interface { + // Init initializes session provider. + Init(gclifetime int64, config string) error + // Read returns raw session store by session ID. + Read(sid string) (RawStore, error) + // Exist returns true if session with given ID exists. + Exist(sid string) bool + // Destroy deletes a session by session ID. + Destroy(sid string) error + // Regenerate regenerates a session store from old session ID to new one. + Regenerate(oldsid, sid string) (RawStore, error) + // Count counts and returns number of sessions. + Count() int + // GC calls GC to clean expired sessions. + GC() +} + +var providers = make(map[string]Provider) + +// Register registers a provider. +func Register(name string, provider Provider) { + if provider == nil { + panic("session: cannot register provider with nil value") + } + if _, dup := providers[name]; dup { + panic(fmt.Errorf("session: cannot register provider '%s' twice", name)) + } + providers[name] = provider +} + +// _____ +// / \ _____ ____ _____ ____ ___________ +// / \ / \\__ \ / \\__ \ / ___\_/ __ \_ __ \ +// / Y \/ __ \| | \/ __ \_/ /_/ > ___/| | \/ +// \____|__ (____ /___| (____ /\___ / \___ >__| +// \/ \/ \/ \//_____/ \/ + +// Manager represents a struct that contains session provider and its configuration. +type Manager struct { + provider Provider + opt Options +} + +// NewManager creates and returns a new session manager by given provider name and configuration. +// It panics when given provider isn't registered. +func NewManager(name string, opt Options) (*Manager, error) { + p, ok := providers[name] + if !ok { + return nil, fmt.Errorf("session: unknown provider '%s'(forgotten import?)", name) + } + return &Manager{p, opt}, p.Init(opt.Maxlifetime, opt.ProviderConfig) +} + +// sessionID generates a new session ID with rand string, unix nano time, remote addr by hash function. +func (m *Manager) sessionID() string { + return hex.EncodeToString(generateRandomKey(m.opt.IDLength / 2)) +} + +// validSessionID tests whether a provided session ID is a valid session ID. +func (m *Manager) validSessionID(sid string) (bool, error) { + if len(sid) != m.opt.IDLength { + return false, fmt.Errorf("invalid 'sid': %s %d != %d", sid, len(sid), m.opt.IDLength) + } + + for i := range sid { + switch { + case '0' <= sid[i] && sid[i] <= '9': + case 'a' <= sid[i] && sid[i] <= 'f': + default: + return false, errors.New("invalid 'sid': " + sid) + } + } + return true, nil +} + +// Start starts a session by generating new one +// or retrieve existence one by reading session ID from HTTP request if it's valid. +func (m *Manager) Start(resp http.ResponseWriter, req *http.Request) (RawStore, error) { + sid := GetCookie(req, m.opt.CookieName) + valid, _ := m.validSessionID(sid) + if len(sid) > 0 && valid && m.provider.Exist(sid) { + return m.provider.Read(sid) + } + + sid = m.sessionID() + sess, err := m.provider.Read(sid) + if err != nil { + return nil, err + } + + cookie := &http.Cookie{ + Name: m.opt.CookieName, + Value: sid, + Path: m.opt.CookiePath, + HttpOnly: true, + Secure: m.opt.Secure, + Domain: m.opt.Domain, + SameSite: m.opt.SameSite, + } + if m.opt.CookieLifeTime >= 0 { + cookie.MaxAge = m.opt.CookieLifeTime + } + http.SetCookie(resp, cookie) + req.AddCookie(cookie) + return sess, nil +} + +// Read returns raw session store by session ID. +func (m *Manager) Read(sid string) (RawStore, error) { + // Ensure we're trying to read a valid session ID + if _, err := m.validSessionID(sid); err != nil { + return nil, err + } + + return m.provider.Read(sid) +} + +// Destroy deletes a session by given ID. +func (m *Manager) Destroy(resp http.ResponseWriter, req *http.Request) error { + sid := GetCookie(req, m.opt.CookieName) + if len(sid) == 0 { + return nil + } + + if _, err := m.validSessionID(sid); err != nil { + return err + } + + if err := m.provider.Destroy(sid); err != nil { + return err + } + cookie := &http.Cookie{ + Name: m.opt.CookieName, + Path: m.opt.CookiePath, + HttpOnly: true, + Expires: time.Now(), + MaxAge: -1, + } + http.SetCookie(resp, cookie) + return nil +} + +// RegenerateID regenerates a session store from old session ID to new one. +func (m *Manager) RegenerateID(resp http.ResponseWriter, req *http.Request) (sess RawStore, err error) { + sid := m.sessionID() + oldsid := GetCookie(req, m.opt.CookieName) + _, err = m.validSessionID(oldsid) + if err != nil { + return nil, err + } + sess, err = m.provider.Regenerate(oldsid, sid) + if err != nil { + return nil, err + } + cookie := &http.Cookie{ + Name: m.opt.CookieName, + Value: sid, + Path: m.opt.CookiePath, + HttpOnly: true, + Secure: m.opt.Secure, + Domain: m.opt.Domain, + SameSite: m.opt.SameSite, + } + if m.opt.CookieLifeTime >= 0 { + cookie.MaxAge = m.opt.CookieLifeTime + } + http.SetCookie(resp, cookie) + req.AddCookie(cookie) + return sess, nil +} + +// Count counts and returns number of sessions. +func (m *Manager) Count() int { + return m.provider.Count() +} + +// GC starts GC job in a certain period. +func (m *Manager) GC() { + m.provider.GC() +} + +// startGC starts GC job in a certain period. +func (m *Manager) startGC() { + m.GC() + time.AfterFunc(time.Duration(m.opt.Gclifetime)*time.Second, func() { m.startGC() }) +} + +// SetSecure indicates whether to set cookie with HTTPS or not. +func (m *Manager) SetSecure(secure bool) { + m.opt.Secure = secure +} diff --git a/vendor/gitea.com/go-chi/session/utils.go b/vendor/gitea.com/go-chi/session/utils.go new file mode 100644 index 0000000000..001bae6d98 --- /dev/null +++ b/vendor/gitea.com/go-chi/session/utils.go @@ -0,0 +1,65 @@ +// Copyright 2013 Beego Authors +// Copyright 2014 The Macaron Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"): you may +// not use this file except in compliance with the License. You may obtain +// a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations +// under the License. + +package session + +import ( + "bytes" + "crypto/rand" + "encoding/gob" + "io" + + "github.com/unknwon/com" +) + +func init() { + gob.Register([]interface{}{}) + gob.Register(map[int]interface{}{}) + gob.Register(map[string]interface{}{}) + gob.Register(map[interface{}]interface{}{}) + gob.Register(map[string]string{}) + gob.Register(map[int]string{}) + gob.Register(map[int]int{}) + gob.Register(map[int]int64{}) +} + +// EncodeGob encodes obj with gob +func EncodeGob(obj map[interface{}]interface{}) ([]byte, error) { + for _, v := range obj { + gob.Register(v) + } + buf := bytes.NewBuffer(nil) + err := gob.NewEncoder(buf).Encode(obj) + return buf.Bytes(), err +} + +// DecodeGob decodes bytes to obj +func DecodeGob(encoded []byte) (out map[interface{}]interface{}, err error) { + buf := bytes.NewBuffer(encoded) + err = gob.NewDecoder(buf).Decode(&out) + return out, err +} + +// NOTE: A local copy in case of underlying package change +var alphanum = []byte("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") + +// generateRandomKey creates a random key with the given strength. +func generateRandomKey(strength int) []byte { + k := make([]byte, strength) + if n, err := io.ReadFull(rand.Reader, k); n != strength || err != nil { + return com.RandomCreateBytes(strength, alphanum...) + } + return k +} |