mirror of
https://github.com/astaxie/beego.git
synced 2024-11-22 21:20:54 +00:00
commit
4e047bd483
25
cache/file.go
vendored
25
cache/file.go
vendored
@ -22,6 +22,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -222,33 +223,13 @@ func exists(path string) (bool, error) {
|
|||||||
// FileGetContents Get bytes to file.
|
// FileGetContents Get bytes to file.
|
||||||
// if non-exist, create this file.
|
// if non-exist, create this file.
|
||||||
func FileGetContents(filename string) (data []byte, e error) {
|
func FileGetContents(filename string) (data []byte, e error) {
|
||||||
f, e := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, os.ModePerm)
|
return ioutil.ReadFile(filename)
|
||||||
if e != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
stat, e := f.Stat()
|
|
||||||
if e != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
data = make([]byte, stat.Size())
|
|
||||||
result, e := f.Read(data)
|
|
||||||
if e != nil || int64(result) != stat.Size() {
|
|
||||||
return nil, e
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// FilePutContents Put bytes to file.
|
// FilePutContents Put bytes to file.
|
||||||
// if non-exist, create this file.
|
// if non-exist, create this file.
|
||||||
func FilePutContents(filename string, content []byte) error {
|
func FilePutContents(filename string, content []byte) error {
|
||||||
fp, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, os.ModePerm)
|
return ioutil.WriteFile(filename, content, os.ModePerm)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer fp.Close()
|
|
||||||
_, err = fp.Write(content)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GobEncode Gob encodes file cache item.
|
// GobEncode Gob encodes file cache item.
|
||||||
|
@ -56,6 +56,7 @@
|
|||||||
package apiauth
|
package apiauth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
@ -128,53 +129,32 @@ func APISecretAuth(f AppIDToAppSecret, timeout int) beego.FilterFunc {
|
|||||||
|
|
||||||
// Signature used to generate signature with the appsecret/method/params/RequestURI
|
// Signature used to generate signature with the appsecret/method/params/RequestURI
|
||||||
func Signature(appsecret, method string, params url.Values, RequestURL string) (result string) {
|
func Signature(appsecret, method string, params url.Values, RequestURL string) (result string) {
|
||||||
var query string
|
var b bytes.Buffer
|
||||||
|
keys := make([]string, len(params))
|
||||||
pa := make(map[string]string)
|
pa := make(map[string]string)
|
||||||
for k, v := range params {
|
for k, v := range params {
|
||||||
pa[k] = v[0]
|
pa[k] = v[0]
|
||||||
|
keys = append(keys, k)
|
||||||
}
|
}
|
||||||
vs := mapSorter(pa)
|
|
||||||
vs.Sort()
|
sort.Strings(keys)
|
||||||
for i := 0; i < vs.Len(); i++ {
|
|
||||||
if vs.Keys[i] == "signature" {
|
for _, key := range keys {
|
||||||
|
if key == "signature" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if vs.Keys[i] != "" && vs.Vals[i] != "" {
|
|
||||||
query = fmt.Sprintf("%v%v%v", query, vs.Keys[i], vs.Vals[i])
|
val := pa[key]
|
||||||
|
if key != "" && val != "" {
|
||||||
|
b.WriteString(key)
|
||||||
|
b.WriteString(val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stringToSign := fmt.Sprintf("%v\n%v\n%v\n", method, query, RequestURL)
|
|
||||||
|
stringToSign := fmt.Sprintf("%v\n%v\n%v\n", method, b.String(), RequestURL)
|
||||||
|
|
||||||
sha256 := sha256.New
|
sha256 := sha256.New
|
||||||
hash := hmac.New(sha256, []byte(appsecret))
|
hash := hmac.New(sha256, []byte(appsecret))
|
||||||
hash.Write([]byte(stringToSign))
|
hash.Write([]byte(stringToSign))
|
||||||
return base64.StdEncoding.EncodeToString(hash.Sum(nil))
|
return base64.StdEncoding.EncodeToString(hash.Sum(nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
type valSorter struct {
|
|
||||||
Keys []string
|
|
||||||
Vals []string
|
|
||||||
}
|
|
||||||
|
|
||||||
func mapSorter(m map[string]string) *valSorter {
|
|
||||||
vs := &valSorter{
|
|
||||||
Keys: make([]string, 0, len(m)),
|
|
||||||
Vals: make([]string, 0, len(m)),
|
|
||||||
}
|
|
||||||
for k, v := range m {
|
|
||||||
vs.Keys = append(vs.Keys, k)
|
|
||||||
vs.Vals = append(vs.Vals, v)
|
|
||||||
}
|
|
||||||
return vs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (vs *valSorter) Sort() {
|
|
||||||
sort.Sort(vs)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (vs *valSorter) Len() int { return len(vs.Keys) }
|
|
||||||
func (vs *valSorter) Less(i, j int) bool { return vs.Keys[i] < vs.Keys[j] }
|
|
||||||
func (vs *valSorter) Swap(i, j int) {
|
|
||||||
vs.Vals[i], vs.Vals[j] = vs.Vals[j], vs.Vals[i]
|
|
||||||
vs.Keys[i], vs.Keys[j] = vs.Keys[j], vs.Keys[i]
|
|
||||||
}
|
|
||||||
|
20
plugins/apiauth/apiauth_test.go
Normal file
20
plugins/apiauth/apiauth_test.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package apiauth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSignature(t *testing.T) {
|
||||||
|
appsecret := "beego secret"
|
||||||
|
method := "GET"
|
||||||
|
RequestURL := "http://localhost/test/url"
|
||||||
|
params := make(url.Values)
|
||||||
|
params.Add("arg1", "hello")
|
||||||
|
params.Add("arg2", "beego")
|
||||||
|
|
||||||
|
signature := "mFdpvLh48ca4mDVEItE9++AKKQ/IVca7O/ZyyB8hR58="
|
||||||
|
if Signature(appsecret, method, params, RequestURL) != signature {
|
||||||
|
t.Error("Signature error")
|
||||||
|
}
|
||||||
|
}
|
@ -15,8 +15,7 @@
|
|||||||
package session
|
package session
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"fmt"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
@ -135,6 +134,9 @@ func (fp *FileProvider) SessionRead(sid string) (Store, error) {
|
|||||||
} else {
|
} else {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
os.Chtimes(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid), time.Now(), time.Now())
|
os.Chtimes(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid), time.Now(), time.Now())
|
||||||
var kv map[interface{}]interface{}
|
var kv map[interface{}]interface{}
|
||||||
b, err := ioutil.ReadAll(f)
|
b, err := ioutil.ReadAll(f)
|
||||||
@ -149,7 +151,7 @@ func (fp *FileProvider) SessionRead(sid string) (Store, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f.Close()
|
|
||||||
ss := &FileSessionStore{sid: sid, values: kv}
|
ss := &FileSessionStore{sid: sid, values: kv}
|
||||||
return ss, nil
|
return ss, nil
|
||||||
}
|
}
|
||||||
@ -204,40 +206,35 @@ func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (Store, error) {
|
|||||||
filepder.lock.Lock()
|
filepder.lock.Lock()
|
||||||
defer filepder.lock.Unlock()
|
defer filepder.lock.Unlock()
|
||||||
|
|
||||||
err := os.MkdirAll(path.Join(fp.savePath, string(oldsid[0]), string(oldsid[1])), 0777)
|
oldPath := path.Join(fp.savePath, string(oldsid[0]), string(oldsid[1]))
|
||||||
if err != nil {
|
oldSidFile := path.Join(oldPath, oldsid)
|
||||||
SLogger.Println(err.Error())
|
newPath := path.Join(fp.savePath, string(sid[0]), string(sid[1]))
|
||||||
}
|
newSidFile := path.Join(newPath, sid)
|
||||||
err = os.MkdirAll(path.Join(fp.savePath, string(sid[0]), string(sid[1])), 0777)
|
|
||||||
if err != nil {
|
// new sid file is exist
|
||||||
SLogger.Println(err.Error())
|
_, err := os.Stat(newSidFile)
|
||||||
}
|
|
||||||
_, err = os.Stat(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid))
|
|
||||||
var newf *os.File
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil, errors.New("newsid exist")
|
return nil, fmt.Errorf("newsid %s exist", newSidFile)
|
||||||
} else if os.IsNotExist(err) {
|
|
||||||
newf, err = os.Create(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = os.Stat(path.Join(fp.savePath, string(oldsid[0]), string(oldsid[1]), oldsid))
|
err = os.MkdirAll(newPath, 0777)
|
||||||
var f *os.File
|
if err != nil {
|
||||||
if err == nil {
|
SLogger.Println(err.Error())
|
||||||
f, err = os.OpenFile(path.Join(fp.savePath, string(oldsid[0]), string(oldsid[1]), oldsid), os.O_RDWR, 0777)
|
|
||||||
io.Copy(newf, f)
|
|
||||||
} else if os.IsNotExist(err) {
|
|
||||||
newf, err = os.Create(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid))
|
|
||||||
} else {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
f.Close()
|
|
||||||
os.Remove(path.Join(fp.savePath, string(oldsid[0]), string(oldsid[1])))
|
// if old sid file exist
|
||||||
os.Chtimes(path.Join(fp.savePath, string(sid[0]), string(sid[1]), sid), time.Now(), time.Now())
|
// 1.read and parse file content
|
||||||
var kv map[interface{}]interface{}
|
// 2.write content to new sid file
|
||||||
b, err := ioutil.ReadAll(newf)
|
// 3.remove old sid file, change new sid file atime and ctime
|
||||||
|
// 4.return FileSessionStore
|
||||||
|
_, err = os.Stat(oldSidFile)
|
||||||
|
if err == nil {
|
||||||
|
b, err := ioutil.ReadFile(oldSidFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var kv map[interface{}]interface{}
|
||||||
if len(b) == 0 {
|
if len(b) == 0 {
|
||||||
kv = make(map[interface{}]interface{})
|
kv = make(map[interface{}]interface{})
|
||||||
} else {
|
} else {
|
||||||
@ -246,10 +243,24 @@ func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (Store, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ioutil.WriteFile(newSidFile, b, 0777)
|
||||||
|
os.Remove(oldSidFile)
|
||||||
|
os.Chtimes(newSidFile, time.Now(), time.Now())
|
||||||
ss := &FileSessionStore{sid: sid, values: kv}
|
ss := &FileSessionStore{sid: sid, values: kv}
|
||||||
return ss, nil
|
return ss, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if old sid file not exist, just create new sid file and return
|
||||||
|
newf, err := os.Create(newSidFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
newf.Close()
|
||||||
|
ss := &FileSessionStore{sid: sid, values: make(map[interface{}]interface{})}
|
||||||
|
return ss, nil
|
||||||
|
}
|
||||||
|
|
||||||
// remove file in save path if expired
|
// remove file in save path if expired
|
||||||
func gcpath(path string, info os.FileInfo, err error) error {
|
func gcpath(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user