提交 629cfe86 编写于 作者: P peterq

add: server端登录及验证功能

上级 2600cf5d
package dep
import (
"math/rand"
"os"
"path/filepath"
"runtime"
"strings"
"time"
)
type tEnv struct {
......@@ -19,6 +21,7 @@ type tEnv struct {
}
func init() {
rand.Seed(time.Now().UnixNano())
Env.Platform = runtime.GOOS
switch Env.Platform {
case "linux", "darwin":
......
......@@ -2,8 +2,11 @@ package functions
import (
"github.com/peterq/pan-light/pc/dep"
"github.com/peterq/pan-light/pc/pan-api"
"github.com/peterq/pan-light/pc/pan-download"
"github.com/peterq/pan-light/pc/server-api"
"github.com/peterq/pan-light/pc/storage"
"log"
"os"
)
......@@ -44,4 +47,41 @@ var baseSyncRoutes = map[string]syncHandler{
},
}
var baseAsyncRoutes = map[string]asyncHandler{}
var baseAsyncRoutes = map[string]asyncHandler{
"api.login": func(p map[string]interface{}, resolve func(interface{}), reject func(interface{}), progress func(interface{}), qmlMsg chan interface{}) {
data, err := server_api.Call("login-token", gson{
"uk": storage.UserState.Uk,
})
if err != nil {
reject(err)
return
}
token := data.(gson)["token"]
filename := data.(gson)["filename"].(string)
if err != nil {
reject(err)
return
}
fid, serverPath, err := pan_api.UploadText(token.(string), "auth."+filename)
if err != nil {
reject(err)
return
}
log.Println(serverPath, filename)
defer pan_api.DeleteFile(serverPath)
link, secret, err := pan_api.ShareFile(fid, "")
log.Println(link, secret, err)
jwt, err := server_api.Call("login", gson{
"link": link,
"secret": secret,
"token": token,
})
storage.UserState.Token = jwt.(string)
if err != nil {
reject(err)
return
}
log.Println(jwt)
resolve(jwt)
},
}
......@@ -13,8 +13,8 @@ func init() {
type syncHandler func(p map[string]interface{}) (result interface{})
type asyncHandler func(map[string]interface{},
func(interface{}), func(interface{}), func(interface{}), chan interface{})
type asyncHandler func(p map[string]interface{},
resolve func(interface{}), reject func(interface{}), progress func(interface{}), qmlMsg chan interface{})
func syncMap(r map[string]syncHandler) {
r1 := map[string]func(map[string]interface{}) interface{}{}
......
......@@ -9,7 +9,7 @@ import (
var UiContext = context.WithValue(context.Background(), "start_time", time.Now())
type gson map[string]interface{}
type gson = map[string]interface{}
func init() {
syncMap(testingSyncRoutes)
......
......@@ -12,6 +12,10 @@ Util.event.once('init.api.ok', function (loginSession) {
appState.loginSession = loginSession
enterPath('/')
console.log('app.js ', JSON.stringify(appState.loginSession))
Util.callGoAsync("api.login")
.then(function (token) {
console.log('登录 pan-light server 成功')
})
})
// 历史记录后退
......
......@@ -56,7 +56,7 @@ Window {
Text {
text: ['<b>pan-light&nbsp;&nbsp;&nbsp;' + window.version + '</b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="'
+ window.userAgreementLink + '" >查看用户协议</a>',
'作&nbsp;&nbsp;&nbsp;&nbsp;者&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PeterQ&lt;<a href="mailto://' + window.email
'作&nbsp;&nbsp;&nbsp;&nbsp;者&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PeterQ&lt;<a href="mailto:' + window.email
+ '" >' + window.email
+ '</a>&gt;', 'Git Repo&nbsp;&nbsp;' + '<a href="' + window.gitRepoUrl
+ '" >' + window.gitRepoUrl + '</a>'].join(
......
......@@ -3,6 +3,7 @@ package pan_api
import (
"encoding/base64"
"fmt"
"github.com/peterq/pan-light/pc/storage"
)
type LoginSessionStruct struct {
......@@ -13,9 +14,11 @@ type LoginSessionStruct struct {
Sign string
Timestamp string
Bdstoken string
Bduss string
}
var LoginSession *LoginSessionStruct
var bduss string
func handleLoginSession(rawJson *tJson) {
LoginSession = new(LoginSessionStruct)
......@@ -26,6 +29,8 @@ func handleLoginSession(rawJson *tJson) {
LoginSession.Sign = sign(raw["sign3"].(string), raw["sign1"].(string))
LoginSession.Timestamp = fmt.Sprint(int(raw["timestamp"].(float64)))
LoginSession.Bdstoken = raw["bdstoken"].(string)
LoginSession.Bduss = bduss
storage.UserState.Uk = fmt.Sprint(int64(raw["uk"].(float64)))
}
func sign(j, r string) string {
a := [256]int{}
......
package pan_api
import (
"bytes"
"crypto/md5"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"github.com/peterq/pan-light/pc/storage"
"io"
"io/ioutil"
"log"
"math/rand"
"mime/multipart"
"net/http"
"net/http/cookiejar"
"net/url"
"regexp"
"strings"
"time"
)
......@@ -21,11 +28,19 @@ var urlMap = map[string]string{
"usage": "https://pan.baidu.com/api/quota",
}
func newRequest(method, url string) *http.Request {
if u, ok := urlMap[url]; ok {
url = u
func newRequest(method, link string, body ...gson) *http.Request {
if u, ok := urlMap[link]; ok {
link = u
}
req, err := http.NewRequest(method, url, nil)
var bd io.Reader
if len(body) == 1 {
formData := url.Values{}
for key, value := range body[0] {
formData.Add(key, fmt.Sprint(value))
}
bd = strings.NewReader(formData.Encode())
}
req, err := http.NewRequest(method, link, bd)
req.Header.Set("user-agent", BaiduUA)
if err != nil {
log.Println(err)
......@@ -45,6 +60,9 @@ func GetSign() (ctx map[string]interface{}, err error) {
Value: c.Value,
Domain: ".baidu.com",
})
if c.Key == "BDUSS" {
bduss = c.Value
}
}
u, _ := url.Parse("https://pan.baidu.com")
cookieJar.SetCookies(u, cookies)
......@@ -224,3 +242,199 @@ func getRedirectedLink(link string) string {
resp.Body.Close()
return end
}
func md5bin(bin []byte) string {
h := md5.New()
h.Write(bin)
return hex.EncodeToString(h.Sum(nil))
}
func UploadText(content string, path string) (fid, serverPath string, err error) {
bin := []byte(content)
md5str := md5bin(bin)
// pre create
data, err := request("POST", "https://pan.baidu.com/api/precreate", gson{
"channel": "chunlei",
"web": 1,
"app_id": 250528,
"bdstoken": LoginSession.Bdstoken,
"logid": time.Now().UnixNano(),
"clienttype": 0,
"startLogTime": time.Now().UnixNano() / int64(time.Millisecond),
}, gson{
"path": path,
"autoinit": 1,
"target_path": "/",
"block_list": fmt.Sprintf("[\"%s\"]", md5str),
"local_mtime": time.Now().Unix(),
})
if err != nil {
return
}
uploadId := data["uploadid"].(string)
// upload
bodyBuf := bytes.NewBuffer([]byte{})
bodyWriter := multipart.NewWriter(bodyBuf)
fileWriter, err := bodyWriter.CreateFormFile("file", "1.txt")
if err != nil {
return
}
fileWriter.Write(bin)
bodyWriter.Close()
req, err := http.NewRequest("POST", "https://qdcu01.pcs.baidu.com/rest/2.0/pcs/superfile2", bodyBuf)
if err != nil {
return
}
req.Header.Set("Content-Type", bodyWriter.FormDataContentType())
req.Header.Set("user-agent", BaiduUA)
params := map[string]interface{}{
"method": "upload",
"app_id": 250528,
"channel": "chunlei",
"clienttype": 0,
"web": 1,
"BDUSS": LoginSession.Bduss,
"logid": time.Now().UnixNano(),
"path": path,
"uploadid": uploadId,
"uploadsign": 0,
"partseq": 0,
}
q := req.URL.Query()
for k, v := range params {
q.Set(k, fmt.Sprint(v))
req.URL.RawQuery = q.Encode()
}
data, err = sendRequest(req)
if err != nil {
return
}
if _, ok := data["md5"]; !ok {
err = errors.New("upload fail")
return
}
blockMd5 := data["md5"].(string)
// combine
data, err = request("POST", "https://pan.baidu.com/api/create", gson{
"isdir": 0,
"rtype": 1,
"channel": "chunlei",
"web": 1,
"app_id": 250528,
"bdstoken": LoginSession.Bdstoken,
"logid": time.Now().UnixNano(),
"clienttype": 0,
}, gson{
"path": path,
"size": len(bin),
"uploadid": uploadId,
"autoinit": 1,
"target_path": "/",
"block_list": fmt.Sprintf("[\"%s\"]", blockMd5),
"local_mtime": time.Now().Unix(),
})
if err != nil {
return
}
log.Println(data)
fid = fmt.Sprint(int64(data["fs_id"].(float64)))
serverPath = data["path"].(string)
return
}
type gson = map[string]interface{}
func request(method, link string, params gson, form gson) (data gson, err error) {
req := newRequest(method, link, form)
q := req.URL.Query()
for k, v := range params {
q.Set(k, fmt.Sprint(v))
}
req.URL.RawQuery = q.Encode()
return sendRequest(req)
}
func sendRequest(req *http.Request) (data gson, err error) {
resp, err := httpClient.Do(req)
if err != nil {
return
}
body := readHtml(resp.Body)
err = json.Unmarshal(tBin(body), &data)
if err != nil {
return
}
if n, ok := data["errno"]; ok && n.(float64) != 0 {
err = errors.New("错误码" + fmt.Sprint(data["errno"]))
}
return
}
func ShareFile(fid, secret string) (link, sec string, err error) {
if len(secret) != 4 {
secret = randomStr(4)
}
sec = secret
data, err := request("POST", "https://pan.baidu.com/share/set", gson{
"channel": "chunlei",
"web": 1,
"app_id": 250528,
"bdstoken": LoginSession.Bdstoken,
"logid": time.Now().UnixNano(),
"clienttype": 0,
}, gson{
"schannel": 4,
"channel_list": "[]",
"period": 7,
"pwd": secret,
"fid_list": fmt.Sprintf("[%s]", fid),
})
if err != nil {
return
}
link = data["link"].(string)
return
}
func randomStr(length int) string {
arr := make([]byte, length)
src := "qwertyuiopasdfghjklzxcvbnm1234567890"
for i := 0; i < length; i++ {
arr[i] = byte(src[rand.Intn(len(src))])
}
return string(arr)
}
func DeleteFile(serverPath string) (err error) {
data, err := request("POST", "https://pan.baidu.com/api/filemanager", gson{
"opera": "delete",
"async": 2,
"onnest": "fail",
"channel": "chunlei",
"web": 1,
"app_id": 250528,
"bdstoken": LoginSession.Bdstoken,
"logid": time.Now().UnixNano(),
"clienttype": 0,
}, gson{
"filelist": fmt.Sprintf("[\"%s\"]", serverPath),
})
if err != nil {
return
}
data, err = request("POST", "https://pan.baidu.com/share/taskquery", gson{
"taskid": int64(data["taskid"].(float64)),
"channel": "chunlei",
"web": "1",
"app_id": "250528",
"bdstoken": LoginSession.Bdstoken,
"logid": time.Now().UnixNano(),
"clienttype": "0",
}, gson{
"filelist": fmt.Sprintf("[\"%s\"]", serverPath),
})
log.Println(data, err)
return
}
package server_api
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"github.com/peterq/pan-light/pc/dep"
"github.com/peterq/pan-light/pc/storage"
"io/ioutil"
"net/http"
)
type gson = map[string]interface{}
var urlMap = map[string]string{
"login-token": "/api/pc/login-token",
"login": "/api/pc/login",
}
var httpClient = http.Client{
//Timeout: 15 * time.Second,
}
func makeRequest(name string, data map[string]interface{}) *http.Request {
bin, _ := json.Marshal(data)
request, _ := http.NewRequest("POST", dep.Env.ApiBase+urlMap[name], bytes.NewReader(bin))
request.Header.Set("User-Agent", dep.Env.ClientUA)
request.Header.Set("Content-Type", "application/json;charset=UTF-8")
request.Header.Set("Authorization", "Bearer "+storage.UserState.Token)
return request
}
func Call(name string, param map[string]interface{}) (result interface{}, err error) {
res, err := httpClient.Do(makeRequest(name, param))
if err != nil {
return
}
bin, err := ioutil.ReadAll(res.Body)
if err != nil {
return
}
var ret gson
err = json.Unmarshal(bin, &ret)
if err == nil {
if !ret["success"].(bool) {
return ret, errors.New(fmt.Sprint("api error(", ret["code"], "): ", ret["message"]))
}
result = ret["result"]
}
return
}
......@@ -81,6 +81,7 @@ type State struct {
PanCookie []*Cookies `protobuf:"bytes,3,rep,name=panCookie,proto3" json:"panCookie,omitempty"`
UserStorage map[string]string `protobuf:"bytes,4,rep,name=userStorage,proto3" json:"userStorage,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Username string `protobuf:"bytes,5,opt,name=username,proto3" json:"username,omitempty"`
Uk string `protobuf:"bytes,6,opt,name=uk,proto3" json:"uk,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
......@@ -146,6 +147,13 @@ func (m *State) GetUsername() string {
return ""
}
func (m *State) GetUk() string {
if m != nil {
return m.Uk
}
return ""
}
type StateSetting struct {
DownloadSegSize int64 `protobuf:"varint,1,opt,name=downloadSegSize,proto3" json:"downloadSegSize,omitempty"`
DownloadCoroutine int64 `protobuf:"varint,2,opt,name=downloadCoroutine,proto3" json:"downloadCoroutine,omitempty"`
......@@ -268,30 +276,31 @@ func init() {
func init() { proto.RegisterFile("storage/types.proto", fileDescriptor_7311ad31e6b1ce7e) }
var fileDescriptor_7311ad31e6b1ce7e = []byte{
// 397 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0xc1, 0x6e, 0xd4, 0x30,
0x10, 0x55, 0xea, 0x6e, 0xb7, 0x99, 0x20, 0xd8, 0x0e, 0x55, 0x65, 0xe5, 0x42, 0x54, 0x81, 0x94,
0x03, 0x0a, 0xd2, 0x72, 0x41, 0x1c, 0x90, 0x50, 0xe1, 0xc0, 0x01, 0x81, 0x1c, 0xf5, 0x03, 0xdc,
0xdd, 0x51, 0x14, 0x6d, 0x6a, 0x47, 0xb6, 0x53, 0x58, 0xae, 0xfc, 0x35, 0x27, 0x14, 0xc7, 0xcd,
0xa6, 0xdb, 0x3d, 0xf4, 0x96, 0x79, 0xf3, 0xde, 0xcc, 0xcb, 0x1b, 0xc3, 0x4b, 0xeb, 0xb4, 0x91,
0x15, 0xbd, 0x73, 0xdb, 0x96, 0x6c, 0xd1, 0x1a, 0xed, 0x34, 0xce, 0x03, 0x78, 0xf9, 0x2f, 0x02,
0xa8, 0x1a, 0x7d, 0x23, 0x9b, 0x2f, 0xd2, 0x49, 0xfc, 0x06, 0xcf, 0x3a, 0x4b, 0xa6, 0x74, 0xd2,
0xd1, 0x77, 0xd9, 0xf2, 0x28, 0x63, 0x79, 0xb2, 0x7c, 0x53, 0x04, 0x7a, 0xb1, 0xa3, 0x16, 0xd7,
0x13, 0xde, 0x57, 0xe5, 0xcc, 0x56, 0x3c, 0x90, 0x62, 0x06, 0xc9, 0xaa, 0x33, 0x86, 0x94, 0xeb,
0x99, 0xfc, 0x28, 0x8b, 0xf2, 0x58, 0x4c, 0x21, 0x2c, 0x00, 0x6b, 0xe5, 0xc8, 0x28, 0xd9, 0x94,
0x64, 0xee, 0xc8, 0xfc, 0xd4, 0xc6, 0x71, 0x96, 0x45, 0x39, 0x13, 0x07, 0x3a, 0xe9, 0x0f, 0x38,
0x7b, 0xb4, 0x14, 0x17, 0xc0, 0x36, 0xb4, 0xe5, 0x91, 0x1f, 0xdf, 0x7f, 0xe2, 0x6b, 0x98, 0xdd,
0xc9, 0xa6, 0x23, 0xbf, 0x32, 0x59, 0x3e, 0x1f, 0xcd, 0xdb, 0x5e, 0x28, 0x86, 0xe6, 0xc7, 0xa3,
0x0f, 0xd1, 0xe5, 0x5f, 0x06, 0x33, 0x0f, 0xe2, 0x39, 0xcc, 0x9c, 0xde, 0x90, 0x0a, 0x73, 0x86,
0x02, 0x97, 0x70, 0x6a, 0xc9, 0xb9, 0x5a, 0x55, 0x36, 0x0c, 0xbb, 0x78, 0x38, 0xac, 0x08, 0x6d,
0x31, 0xf2, 0xb0, 0x80, 0xb8, 0x95, 0xea, 0x4a, 0xeb, 0x4d, 0x4d, 0x9c, 0xf9, 0xf8, 0x16, 0xa3,
0x68, 0xe5, 0x61, 0x2b, 0x76, 0x14, 0xfc, 0x0c, 0xc9, 0x10, 0x9b, 0x67, 0xf0, 0x63, 0xaf, 0x78,
0xb5, 0xb7, 0xe6, 0x7a, 0xc7, 0x18, 0xa2, 0x9e, 0x6a, 0x30, 0x85, 0xd3, 0xbe, 0x54, 0xf2, 0x96,
0xf8, 0xcc, 0xfb, 0x1f, 0xeb, 0x54, 0xc2, 0x3c, 0x58, 0xc3, 0x1c, 0x5e, 0xac, 0xf5, 0x2f, 0xd5,
0x68, 0xb9, 0x2e, 0xa9, 0x2a, 0xeb, 0x3f, 0xe4, 0xff, 0x96, 0x89, 0x7d, 0x18, 0xdf, 0xc2, 0xd9,
0x3d, 0x74, 0xa5, 0x8d, 0xee, 0x5c, 0xad, 0x86, 0x34, 0x99, 0x78, 0xdc, 0x48, 0x3f, 0xc1, 0x62,
0xdf, 0xdf, 0x81, 0xab, 0x9c, 0x4f, 0xaf, 0x12, 0x4f, 0xaf, 0xb0, 0x82, 0x79, 0xc8, 0xe5, 0xa9,
0x32, 0xbc, 0x80, 0x93, 0xb5, 0xbe, 0x95, 0xb5, 0xf2, 0xaf, 0x25, 0x16, 0xa1, 0x42, 0x0e, 0x73,
0xfa, 0xdd, 0xd6, 0x86, 0x2c, 0x3f, 0xf6, 0x76, 0xef, 0xcb, 0x9b, 0x13, 0xff, 0xee, 0xdf, 0xff,
0x0f, 0x00, 0x00, 0xff, 0xff, 0x78, 0x36, 0x24, 0x2c, 0x0e, 0x03, 0x00, 0x00,
// 408 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0xc1, 0x6e, 0xd3, 0x40,
0x10, 0x95, 0xb3, 0x4d, 0xd2, 0x4c, 0x50, 0x49, 0x87, 0xaa, 0x5a, 0xf9, 0x82, 0x55, 0x81, 0xe4,
0x03, 0x32, 0x52, 0xb8, 0x20, 0x0e, 0x48, 0xa8, 0x70, 0xe0, 0x80, 0x40, 0x6b, 0xf5, 0x03, 0xb6,
0xc9, 0xc8, 0xb2, 0xec, 0xee, 0x5a, 0xbb, 0xeb, 0x42, 0xf8, 0x0d, 0xfe, 0x96, 0x13, 0xf2, 0x7a,
0xeb, 0xb8, 0x69, 0x0e, 0xdc, 0x3c, 0x6f, 0xde, 0x9b, 0x79, 0x7e, 0x63, 0xc3, 0x0b, 0xeb, 0xb4,
0x91, 0x05, 0xbd, 0x75, 0xbb, 0x86, 0x6c, 0xd6, 0x18, 0xed, 0x34, 0xce, 0x03, 0x78, 0xf5, 0x37,
0x02, 0x28, 0x6a, 0x7d, 0x2b, 0xeb, 0xcf, 0xd2, 0x49, 0xfc, 0x0a, 0xcf, 0x5a, 0x4b, 0x26, 0x77,
0xd2, 0xd1, 0x37, 0xd9, 0xf0, 0x28, 0x61, 0xe9, 0x72, 0xfd, 0x3a, 0x0b, 0xf4, 0x6c, 0x4f, 0xcd,
0x6e, 0x46, 0xbc, 0x2f, 0xca, 0x99, 0x9d, 0x78, 0x24, 0xc5, 0x04, 0x96, 0x9b, 0xd6, 0x18, 0x52,
0xae, 0x63, 0xf2, 0x49, 0x12, 0xa5, 0x0b, 0x31, 0x86, 0x30, 0x03, 0x2c, 0x95, 0x23, 0xa3, 0x64,
0x9d, 0x93, 0xb9, 0x27, 0xf3, 0x43, 0x1b, 0xc7, 0x59, 0x12, 0xa5, 0x4c, 0x1c, 0xe9, 0xc4, 0xdf,
0xe1, 0xfc, 0xc9, 0x52, 0x5c, 0x01, 0xab, 0x68, 0xc7, 0x23, 0x3f, 0xbe, 0x7b, 0xc4, 0x57, 0x30,
0xbd, 0x97, 0x75, 0x4b, 0x7e, 0xe5, 0x72, 0x7d, 0x36, 0x98, 0xb7, 0x9d, 0x50, 0xf4, 0xcd, 0x0f,
0x93, 0xf7, 0xd1, 0xd5, 0x1f, 0x06, 0x53, 0x0f, 0xe2, 0x05, 0x4c, 0x9d, 0xae, 0x48, 0x85, 0x39,
0x7d, 0x81, 0x6b, 0x38, 0xb5, 0xe4, 0x5c, 0xa9, 0x0a, 0x1b, 0x86, 0x5d, 0x3e, 0x1e, 0x96, 0x85,
0xb6, 0x18, 0x78, 0x98, 0xc1, 0xa2, 0x91, 0xea, 0x5a, 0xeb, 0xaa, 0x24, 0xce, 0x7c, 0x7c, 0xab,
0x41, 0xb4, 0xf1, 0xb0, 0x15, 0x7b, 0x0a, 0x7e, 0x82, 0x65, 0x1f, 0x9b, 0x67, 0xf0, 0x13, 0xaf,
0x78, 0x79, 0xb0, 0xe6, 0x66, 0xcf, 0xe8, 0xa3, 0x1e, 0x6b, 0x30, 0x86, 0xd3, 0xae, 0x54, 0xf2,
0x8e, 0xf8, 0xd4, 0xfb, 0x1f, 0x6a, 0x3c, 0x83, 0x49, 0x5b, 0xf1, 0x99, 0x47, 0x27, 0x6d, 0x15,
0x4b, 0x98, 0x07, 0xab, 0x98, 0xc2, 0xf3, 0xad, 0xfe, 0xa9, 0x6a, 0x2d, 0xb7, 0x39, 0x15, 0x79,
0xf9, 0x9b, 0xfc, 0xdb, 0x33, 0x71, 0x08, 0xe3, 0x1b, 0x38, 0x7f, 0x80, 0xae, 0xb5, 0xd1, 0xad,
0x2b, 0x55, 0x9f, 0x2e, 0x13, 0x4f, 0x1b, 0xf1, 0x47, 0x58, 0x1d, 0xfa, 0x3d, 0x72, 0xa5, 0x8b,
0xf1, 0x95, 0x16, 0xe3, 0xab, 0x6c, 0x60, 0x1e, 0x72, 0xfa, 0x5f, 0x19, 0x5e, 0xc2, 0x6c, 0xab,
0xef, 0x64, 0xa9, 0xfc, 0xd7, 0xb3, 0x10, 0xa1, 0x42, 0x0e, 0x73, 0xfa, 0xd5, 0x94, 0x86, 0x2c,
0x3f, 0xf1, 0x76, 0x1f, 0xca, 0xdb, 0x99, 0xff, 0x0f, 0xde, 0xfd, 0x0b, 0x00, 0x00, 0xff, 0xff,
0xbd, 0xf4, 0x07, 0xf5, 0x1e, 0x03, 0x00, 0x00,
}
......@@ -18,6 +18,7 @@ message state {
repeated cookies panCookie = 3;
map<string, string> userStorage = 4;
string username = 5;
string uk = 6;
}
message cookies {
......
package artisan
type AppError interface {
error
Code() int
Parent() error
}
type NormalError struct {
code int
message string
parent error
}
func (e *NormalError) Error() string {
if e.parent != nil {
return e.message + ": " + e.parent.Error()
}
return e.message
}
func (e *NormalError) Code() int {
return e.code
}
func (e *NormalError) Parent() error {
return e.parent
}
func NewError(message string, code int, parent error) *NormalError {
return &NormalError{
code: code,
message: message,
parent: parent,
}
}
func ErrorFrom(err error) AppError {
if e, ok := err.(AppError); ok {
return e
}
return NewError(err.Error(), -1, nil)
}
package artisan
import (
"crypto/md5"
"encoding/hex"
)
func Md5bin(bin []byte) string {
h := md5.New()
h.Write(bin)
return hex.EncodeToString(h.Sum(nil))
}
package artisan
import "github.com/kataras/iris/context"
func ApiHandler(handler func(ctx context.Context, param map[string]interface{}) (result interface{}, err error)) func(ctx context.Context) {
return func(ctx context.Context) {
var param map[string]interface{}
var result interface{}
err := ctx.ReadJSON(&param)
if err == nil {
defer func() {
if err := recover(); err != nil {
if e1, ok := err.(error); !ok {
panic(e1)
}
ctx.JSON(map[string]interface{}{
"success": false,
"message": err.(error).Error(),
"code": ErrorFrom(err.(error)).Code(),
})
}
}()
result, err = handler(ctx, param)
} else {
err = NewError("decode input json error", -1, err)
}
if err != nil {
ctx.JSON(map[string]interface{}{
"success": false,
"message": err.Error(),
"code": ErrorFrom(err.(error)).Code(),
})
} else {
ctx.JSON(map[string]interface{}{
"success": true,
"result": result,
})
}
}
}
package conf
import (
"github.com/kataras/iris"
"gopkg.in/mgo.v2"
"os"
"strings"
)
type conf struct {
AppSecret string
MongodbUri string
Database string
}
var Conf *conf
var IrisConf iris.Configuration
var MongodbSession *mgo.Session
func init() {
confFile, ok := os.LookupEnv("pan_light_server_conf")
if !ok {
panic("the conf path must be specified")
}
IrisConf = iris.YAML(confFile)
Conf = &conf{
AppSecret: getConf("app-secret").(string),
MongodbUri: getConf("mongodb-uri").(string),
Database: getConf("database").(string),
}
var err error
MongodbSession, err = mgo.Dial(Conf.MongodbUri)
if err != nil {
panic(err)
}
MongodbSession.Refresh()
}
func getConf(key string) interface{} {
p := strings.Split(key, ".")
cnf := IrisConf.Other
var parent map[interface{}]interface{}
for idx, name := range p {
if len(p) == 1 {
return cnf[name]
}
if idx == len(p)-1 {
return parent[name]
}
parent = parent[name].(map[interface{}]interface{})
}
return nil
}
package conf
const (
CollectionVip string = "vip"
CollectionVipSaveFile = "vip_save_file"
CollectionUser = "user"
)
const (
JwtPcLogin string = "pc-login"
)
const (
CtxPcLogin string = "pc-login"
)
package dao
import (
"errors"
"github.com/peterq/pan-light/server/conf"
"gopkg.in/mgo.v2"
)
type gson = map[string]interface{}
var UserDao = &userDao{}
type UserModel struct {
Uk string // 百度 uk
MarkUsername string // 脱敏 用户名
Username string `json:"username,omitempty"` // 用户名
Avatar string
IsVip bool
IsSuperVip bool
}
type userDao struct{}
func (d *userDao) UpInsert(model UserModel) (err error) {
if model.Uk == "" {
return errors.New("uk empty")
}
s := conf.MongodbSession.Clone()
defer s.Refresh()
collection := d.collection(s)
_, err = collection.Upsert(gson{
"uk": model.Uk,
}, model)
return
}
func (d *userDao) collection(s *mgo.Session) *mgo.Collection {
return s.DB(conf.Conf.Database).C(conf.CollectionUser)
}
func (d *userDao) GetByUk(uk string) (*UserModel, error) {
s := conf.MongodbSession.Clone()
defer s.Refresh()
collection := d.collection(s)
var model UserModel
err := collection.Find(gson{
"uk": uk,
}).One(&model)
return &model, err
}
package dao
import (
"github.com/peterq/pan-light/server/conf"
"gopkg.in/mgo.v2"
)
type VipModel struct {
Username string
Bduss string
}
type vipDao struct{}
func (*vipDao) collection(s *mgo.Session) *mgo.Collection {
return s.DB(conf.Conf.Database).C(conf.CollectionVip)
}
func (d *vipDao) GetAll() (data []VipModel, err error) {
s := conf.MongodbSession.Clone()
defer s.Refresh()
collection := d.collection(s)
err = collection.Find(nil).All(&data)
return
}
var Vip = &vipDao{}
module github.com/peterq/pan-light/server
require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/iris-contrib/middleware v0.0.0-20181021162728-8bd5d51b3c2e
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 // indirect
github.com/juju/testing v0.0.0-20190429233213-dfc56b8c09fc // indirect
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect
github.com/kataras/iris v11.1.1+incompatible
github.com/kr/pretty v0.1.0 // indirect
github.com/mattn/go-colorable v0.1.2 // indirect
github.com/onsi/ginkgo v1.8.0 // indirect
github.com/onsi/gomega v1.5.0 // indirect
github.com/pkg/errors v0.8.0
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a // indirect
github.com/yudai/pp v2.0.1+incompatible // indirect
golang.org/x/net v0.0.0-20190311183353-d8887717615a
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed // indirect
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce
)
// replace github.com/peterq/pan-light => ../
github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Joker/hpp v0.0.0-20180418125244-6893e659854a h1:PiDAizhfJbwZMISZ1Itx1ZTFeOFCml89Ofmz3V8rhoU=
github.com/Joker/hpp v0.0.0-20180418125244-6893e659854a/go.mod h1:MzD2WMdSxvbHw5fM/OXOFily/lipJWRc9C1px0Mt0ZE=
github.com/Joker/jade v1.0.0 h1:lOCEPvTAtWfLpSZYMOv/g44MGQFAolbKh2khHHGu0Kc=
github.com/Joker/jade v1.0.0/go.mod h1:efZIdO0py/LtcJRSa/j2WEklMSAw84WV0zZVMxNToB8=
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398 h1:WDC6ySpJzbxGWFh4aMxFFC28wwGp5pEuoTtvA4q/qQ4=
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f h1:zvClvFQwU++UpIUBGC8YmDlfhUrweEy1R1Fj1gu5iIM=
github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
github.com/aymerick/raymond v2.0.2+incompatible h1:VEp3GpgdAnv9B2GFyTvqgcKvY+mfKMjPOA3SbKLtnU0=
github.com/aymerick/raymond v2.0.2+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
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/dgraph-io/badger v1.5.4/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-farm v0.0.0-20180109070241-2de33835d102/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
......@@ -19,12 +24,22 @@ github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/flosch/pongo2 v0.0.0-20180809100617-24195e6d38b0 h1:ZHx2BEERvWkuwuE7qWN9TuRxucHDH2JrsvneZjVJfo0=
github.com/flosch/pongo2 v0.0.0-20180809100617-24195e6d38b0/go.mod h1:rE0ErqqBaMcp9pzj8JxV1GcfDBpuypXYxlR1c37AUwg=
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/gavv/monotime v0.0.0-20171021193802-6f8212e8d10d h1:oYXrtNhqNKL1dVtKdv8XUq5zqdGVFNQ0/4tvccXZOLM=
github.com/gavv/monotime v0.0.0-20171021193802-6f8212e8d10d/go.mod h1:vmp8DIyckQMXOPl0AQVHt+7n5h7Gb7hS6CUydiV8QeA=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/imkira/go-interpol v1.1.0 h1:KIiKr0VSG2CUW1hl1jpiyuzuJeKUUpC8iM1AIE7N1Vk=
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
github.com/iris-contrib/blackfriday v2.0.0+incompatible h1:o5sHQHHm0ToHUlAJSTjW9UWicjJSDDauOOQ2AHuIVp4=
github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI=
......@@ -32,12 +47,23 @@ github.com/iris-contrib/formBinder v0.0.0-20190104093907-fbd5963f41e1 h1:7GsNnSL
github.com/iris-contrib/formBinder v0.0.0-20190104093907-fbd5963f41e1/go.mod h1:i8kTYUOEstd/S8TG0ChTXQdf4ermA/e8vJX0+QruD9w=
github.com/iris-contrib/go.uuid v2.0.0+incompatible h1:XZubAYg61/JwnJNbZilGjf3b3pB80+OQg2qf6c8BfWE=
github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0=
github.com/iris-contrib/httpexpect v0.0.0-20180314041918-ebe99fcebbce h1:q8Ka/exfHNgK7izJE+aUOZd7KZXJ7oQbnJWiZakEiMo=
github.com/iris-contrib/httpexpect v0.0.0-20180314041918-ebe99fcebbce/go.mod h1:VER17o2JZqquOx41avolD/wMGQSFEFBKWmhag9/RQRY=
github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI=
github.com/iris-contrib/middleware v0.0.0-20181021162728-8bd5d51b3c2e h1:kj3vB5WsLvahUNG7X6TDRXuYlTNgcZGMFmrd4fmAk6A=
github.com/iris-contrib/middleware v0.0.0-20181021162728-8bd5d51b3c2e/go.mod h1:lZivVjxn00uQH7vp452Wa2p9GD+2ElkVms944o+f0+Y=
github.com/json-iterator/go v1.1.5 h1:gL2yXlmiIo4+t+y32d4WGwOjKGYcGOuyrg46vadswDE=
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
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/juju/errors v0.0.0-20181012004132-a4583d0a56ea h1:g2k+8WR7cHch4g0tBDhfiEvAp7fXxTNBiD1oC1Oxj3E=
github.com/juju/errors v0.0.0-20181012004132-a4583d0a56ea/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q=
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8 h1:UUHMLvzt/31azWTN/ifGWef4WUqvXk0iRqdhdy/2uzI=
github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
github.com/juju/testing v0.0.0-20190429233213-dfc56b8c09fc h1:5xUWujf6ES9tEpFHFzI34vcHm8U07lGjxAuJML3qwqM=
github.com/juju/testing v0.0.0-20190429233213-dfc56b8c09fc/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 h1:uC1QfSlInpQF+M0ao65imhwqKnz3Q2z/d8PWZRMQvDM=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/kataras/golog v0.0.0-20180321173939-03be10146386 h1:VT6AeCHO/mc+VedKBMhoqb5eAK8B1i9F6nZl7EGlHvA=
github.com/kataras/golog v0.0.0-20180321173939-03be10146386/go.mod h1:PcaEvfvhGsqwXZ6S3CgCbmjcp+4UDUh2MIfF2ZEul8M=
github.com/kataras/iris v11.1.1+incompatible h1:aImj8YY2PWCRJfHX4qhWmnqmCuii91EDtHB70K42YhM=
......@@ -48,37 +74,89 @@ github.com/klauspost/compress v1.4.1 h1:8VMb5+0wMgdBykOV96DwNwKFQ+WTI4pzYURP99Cc
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/microcosm-cc/bluemonday v1.0.1 h1:SIYunPjnlXcW+gVfvm0IlSeR5U3WZUOLfVmqg85Go44=
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs=
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
github.com/peterq/pan-light v0.0.0-20190404010923-7fa89d3a5d00 h1:FrhgBxO/gM01gHd+Xr59wbSceUpIg/iBeMQITElVlH0=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pkg/errors v0.8.0 h1:WdK/asTD0HN+q6hsWO3/vpuAkAr+tw6aNJNDFFf0+qw=
github.com/pkg/errors v0.8.0/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/ryanuber/columnize v2.1.0+incompatible h1:j1Wcmh8OrK4Q7GXY+V7SVSY8nUWQxHW5TkBe7YUl+2s=
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95 h1:/vdW8Cb7EXrkqWGufVMES1OH2sU9gKVb2n9/1y5NMBY=
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v0.0.0-20181112162635-ac52e6811b56 h1:yhqBHs09SmmUoNOHc9jgK4a60T3XFRtPAkYxVnqgY50=
github.com/xeipuuv/gojsonschema v0.0.0-20181112162635-ac52e6811b56/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0 h1:6fRhSjgLCkTD3JnJxvaJ4Sj+TYblw757bqYgZaOq5ZY=
github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI=
github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA=
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M=
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
github.com/yudai/pp v2.0.1+incompatible h1:Q4//iY4pNF6yPLZIigmvcl7k/bPgrcTPIFIcmawg5bI=
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869 h1:kkXA53yGe04D0adEYJwEVQjeBppL01Exg+fnMjfUraU=
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a h1:gOpx8G595UYyvj8UK4+OFyY4rx037g3fmfhe5SasG3U=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed h1:uPxWBzB3+mlnjy9W58qY1j/cjyFjutgw/Vhan2zLy/A=
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384 h1:TFlARGu6Czu1z7q93HTxcP1P+/ZFC/IKythI5RzrnRg=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/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.39.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce h1:xcEWjVhvbDy+nHP67nPDDpbYrY+ILlfndk4bRioVHaU=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
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 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
......@@ -3,6 +3,7 @@ package main
import (
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/peterq/pan-light/server/pc-api"
"log"
)
......@@ -12,5 +13,6 @@ func main() {
app.Get("/", func(ctx context.Context) {
ctx.Write([]byte("Hello pan-light"))
})
pc_api.Init(app)
app.Run(iris.Addr("127.0.0.1:8081"))
}
package pan_viper
import (
"fmt"
"github.com/pkg/errors"
"io"
"log"
"math"
"net/http"
"net/http/cookiejar"
"net/url"
"strings"
"time"
)
type gson = map[string]interface{}
const baiduUa = "netdisk;4.6.2.0;PC;PC-Windows;10.0.10240;WindowsBaiduYunGuanJia"
func makeHttpClient(bduss string) http.Client {
jar, _ := cookiejar.New(nil)
u, _ := url.Parse("https://pan.baidu.com")
jar.SetCookies(u, []*http.Cookie{
{
Name: "BDUSS",
Value: bduss,
Path: "/",
HttpOnly: false,
MaxAge: math.MaxInt32,
Domain: "*.baidu.com",
},
})
httpClient := http.Client{
Transport: nil,
CheckRedirect: func(req *http.Request, via []*http.Request) error {
req.Header.Del("Referer")
log.Println(req.URL)
if len(via) >= 10 {
return errors.New("stopped after 10 redirects")
}
return nil
},
Jar: jar,
Timeout: 15 * time.Second,
}
return httpClient
}
func newRequest(method, link string, body ...gson) *http.Request {
var bd io.Reader
if len(body) == 1 {
formData := url.Values{}
for key, value := range body[0] {
formData.Add(key, fmt.Sprint(value))
}
bd = strings.NewReader(formData.Encode())
}
req, err := http.NewRequest(method, link, bd)
req.Header.Set("user-agent", baiduUa)
req.Header.Set("referer", "https://pan.baidu.com")
if err != nil {
log.Println(err)
}
return req
}
package pan_viper
import (
"encoding/json"
"fmt"
"github.com/peterq/pan-light/server/dao"
"github.com/pkg/errors"
"io/ioutil"
"net/http"
"regexp"
"strings"
"sync"
"time"
)
var vipMap = map[string]*Vip{}
func init() {
data, err := dao.Vip.GetAll()
if err != nil {
panic(err)
}
for _, model := range data {
vipMap[model.Username] = &Vip{
http: makeHttpClient(model.Bduss),
username: model.Username,
}
}
}
type loginSession struct {
}
type Vip struct {
http http.Client
username string
_loginSession loginSession
loginSessionLock sync.RWMutex
}
func (v *Vip) loginSession() loginSession {
v.loginSessionLock.RLock()
defer v.loginSessionLock.RUnlock()
return v._loginSession
}
func (v *Vip) Username() string {
return v.username
}
func (v *Vip) CreateSession() {
//v.request()
}
func (v *Vip) LoadShareFilenameAndUk(link, secret string) (uk, filename string, share gson, err error) {
err = v.inputSharePwd(link, secret)
if err != nil {
err = errors.Wrap(err, "input pwd error")
}
resp, err := v.http.Get(link)
if err != nil {
err = errors.Wrap(err, "load share page error")
return
}
bin, err := ioutil.ReadAll(resp.Body)
if err != nil {
err = errors.Wrap(err, "load share page error")
return
}
body := string(bin)
reg := regexp.MustCompile(`setData\(({.*})\);\n`)
find := reg.FindStringSubmatch(body)
if len(find) != 2 {
err = errors.New("load share info error")
}
err = json.Unmarshal([]byte(find[1]), &share)
if err != nil {
err = errors.Wrap(err, "decode share info error")
return
}
uk = fmt.Sprint(int64(share["uk"].(float64)))
code := int64(share["file_list"].(gson)["errno"].(float64))
if code != 0 {
err = errors.New("share error code: " + fmt.Sprint(code))
return
}
filename = share["file_list"].(gson)["list"].([]interface{})[0].(gson)["server_filename"].(string)
return
}
func (v *Vip) inputSharePwd(link, secret string) (err error) {
t := strings.Split(link, "/")
surl := t[len(t)-1]
t = strings.Split(surl, "")
t = t[1:]
surl = strings.Join(t, "")
_, err = v.request("POST", "https://pan.baidu.com/share/verify", gson{
"surl": surl,
"t": time.Now().UnixNano() / int64(time.Millisecond),
"channel": "chunlei",
"web": 1,
"app_id": 250528,
"bdstoken": "null",
"logid": time.Now().UnixNano(),
"clienttype": 0,
}, gson{
"pwd": secret,
"vcode": "",
"vcode_str": "",
})
return
}
func (v *Vip) request(method, link string, params gson, form gson) (data gson, err error) {
req := newRequest(method, link, form)
q := req.URL.Query()
for k, v := range params {
q.Set(k, fmt.Sprint(v))
}
req.URL.RawQuery = q.Encode()
resp, err := v.http.Do(req)
if err != nil {
err = errors.Wrap(err, "http request error")
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
err = errors.Wrap(err, "read http resp error")
return
}
err = json.Unmarshal([]byte(body), &data)
if err != nil {
return
}
if n, ok := data["errno"]; ok && n.(float64) != 0 {
err = errors.New("pan api error code " + fmt.Sprint(data["errno"]))
}
return
}
func GetVip() *Vip {
for _, value := range vipMap {
return value
}
return nil
}
package pc_api
import (
"fmt"
"github.com/kataras/iris/context"
"github.com/peterq/pan-light/server/artisan"
"github.com/peterq/pan-light/server/conf"
"github.com/peterq/pan-light/server/dao"
"github.com/peterq/pan-light/server/pan-viper"
"github.com/peterq/pan-light/server/pc-api/middleware"
"strings"
"time"
)
type gson = map[string]interface{}
func handleLoginToken(ctx context.Context, param map[string]interface{}) (result interface{}, err error) {
uk := param["uk"].(string)
filename := artisan.Md5bin([]byte(fmt.Sprint(time.Now().UnixNano())))
filename = filename[:8]
token, e := middleware.NewJwtToken(time.Minute*5, map[string]interface{}{
"need-login": uk,
"filename": filename,
})
result = gson{
"token": token,
"filename": filename,
}
if e != nil {
err = artisan.NewError("generate jwt error", -1, e)
}
return
}
func handleLogin(ctx context.Context, param map[string]interface{}) (result interface{}, err error) {
link := param["link"].(string)
secret := param["secret"].(string)
token := param["token"].(string)
claim, e := middleware.ParseToken(token)
if e != nil {
err = artisan.NewError("token invalid", -1, e)
return
}
uk := claim["need-login"].(string)
fn := claim["filename"].(string)
ukShare, filename, share, err := pan_viper.GetVip().LoadShareFilenameAndUk(link, secret)
if err != nil {
err = artisan.NewError("读取分享列表错误", -1, err)
return
}
if ukShare != uk {
err = artisan.NewError("uk not match", -1, err)
return
}
if !strings.Contains(filename, fn) {
err = artisan.NewError("share file invalid", -1, err)
return
}
dao.UserDao.UpInsert(dao.UserModel{
Uk: uk,
MarkUsername: share["linkusername"].(string),
Avatar: share["photo"].(string),
IsVip: share["is_master_vip"].(float64) == 1,
IsSuperVip: share["is_master_svip"].(float64) == 1,
})
result, err = middleware.NewJwtToken(time.Hour*24*30, gson{
"type": conf.JwtPcLogin,
"uk": uk,
})
return
}
func handleFeedBack(ctx context.Context, param map[string]interface{}) (result interface{}, err error) {
result = ctx.Values().Get(conf.CtxPcLogin).(*middleware.PcLoginInfo).User()
return
}
package middleware
import (
"errors"
"github.com/dgrijalva/jwt-go"
jwtmiddleware "github.com/iris-contrib/middleware/jwt"
"github.com/kataras/iris"
"github.com/kataras/iris/context"
"github.com/peterq/pan-light/server/conf"
"github.com/peterq/pan-light/server/dao"
"runtime/debug"
"time"
)
type PcLoginInfo struct {
uk string
user *dao.UserModel
}
func (p *PcLoginInfo) User() *dao.UserModel {
if p.user == nil {
p.user, _ = dao.UserDao.GetByUk(p.uk)
}
return p.user
}
func (p *PcLoginInfo) Uk() string {
return p.uk
}
var PcJwtHandler = jwtmiddleware.New(jwtmiddleware.Config{
ValidationKeyGetter: func(token *jwt.Token) (interface{}, error) {
return []byte(conf.Conf.AppSecret), nil
},
SigningMethod: jwt.SigningMethodHS256,
ErrorHandler: func(ctx context.Context, err string) {
ctx.StatusCode(iris.StatusUnauthorized)
ctx.JSON(map[string]interface{}{
"success": false,
"message": "jwt token check error: " + err,
"code": iris.StatusUnauthorized,
})
debug.PrintStack()
},
})
// 校验pc端jwt
func PcJwtAuth(ctx context.Context) {
if err := PcJwtHandler.CheckJWT(ctx); err != nil {
ctx.StopExecution()
return
}
token := PcJwtHandler.Get(ctx)
claim := token.Claims.(jwt.MapClaims)
if claim["type"].(string) != conf.JwtPcLogin {
ctx.StopExecution()
return
}
loginInfo := &PcLoginInfo{
uk: claim["uk"].(string),
}
ctx.Values().Set(conf.CtxPcLogin, loginInfo)
ctx.Next()
}
func NewJwtToken(expireIn time.Duration, info map[string]interface{}) (string, error) {
token := jwt.New(jwt.SigningMethodHS256)
claims := make(jwt.MapClaims)
claims["exp"] = time.Now().Add(expireIn).Unix()
claims["iat"] = time.Now().Unix()
if info != nil {
for key, value := range info {
claims[key] = value
}
}
token.Claims = claims
return token.SignedString([]byte(conf.Conf.AppSecret))
}
func ParseToken(token string) (claim jwt.MapClaims, err error) {
parsedToken, err := jwt.Parse(token, PcJwtHandler.Config.ValidationKeyGetter)
if err != nil {
return
}
if !parsedToken.Valid {
err = errors.New("token invalid")
return
}
claim = parsedToken.Claims.(jwt.MapClaims)
if expired := claim.VerifyExpiresAt(time.Now().Unix(), true); !expired {
err = errors.New("token is expired")
return
}
return
}
package pc_api
import (
"github.com/kataras/iris"
"github.com/peterq/pan-light/server/artisan"
"github.com/peterq/pan-light/server/pc-api/middleware"
)
func Init(app *iris.Application) {
app.Post("api/pc/login-token", artisan.ApiHandler(handleLoginToken))
app.Post("api/pc/login", artisan.ApiHandler(handleLogin))
pc := app.Party("api/pc/")
pc.Use(middleware.PcJwtAuth)
pc.Done()
pc.Post("feedback", artisan.ApiHandler(handleFeedBack))
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册