mirror of
				https://github.com/cloudreve/cloudreve.git
				synced 2025-10-31 16:49:03 +08:00 
			
		
		
		
	Test: qiniu handler get token
This commit is contained in:
		| @ -10,6 +10,7 @@ import ( | |||||||
| 	"github.com/HFO4/cloudreve/pkg/util" | 	"github.com/HFO4/cloudreve/pkg/util" | ||||||
| 	"github.com/gin-gonic/gin" | 	"github.com/gin-gonic/gin" | ||||||
| 	"github.com/jinzhu/gorm" | 	"github.com/jinzhu/gorm" | ||||||
|  | 	"github.com/qiniu/api.v7/v7/auth/qbox" | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/http/httptest" | 	"net/http/httptest" | ||||||
| @ -342,3 +343,84 @@ func TestRemoteCallbackAuth(t *testing.T) { | |||||||
| 		asserts.True(c.IsAborted()) | 		asserts.True(c.IsAborted()) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func TestQiniuCallbackAuth(t *testing.T) { | ||||||
|  | 	asserts := assert.New(t) | ||||||
|  | 	rec := httptest.NewRecorder() | ||||||
|  | 	AuthFunc := QiniuCallbackAuth() | ||||||
|  |  | ||||||
|  | 	// Callback Key 相关验证失败 | ||||||
|  | 	{ | ||||||
|  | 		c, _ := gin.CreateTestContext(rec) | ||||||
|  | 		c.Params = []gin.Param{ | ||||||
|  | 			{"key", "testQiniuBackRemote"}, | ||||||
|  | 		} | ||||||
|  | 		c.Request, _ = http.NewRequest("POST", "/api/v3/callback/remote/testQiniuBackRemote", nil) | ||||||
|  | 		AuthFunc(c) | ||||||
|  | 		asserts.True(c.IsAborted()) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// 成功 | ||||||
|  | 	{ | ||||||
|  | 		cache.Set( | ||||||
|  | 			"callback_testCallBackQiniu", | ||||||
|  | 			serializer.UploadSession{ | ||||||
|  | 				UID:         1, | ||||||
|  | 				PolicyID:    2, | ||||||
|  | 				VirtualPath: "/", | ||||||
|  | 			}, | ||||||
|  | 			0, | ||||||
|  | 		) | ||||||
|  | 		cache.Deletes([]string{"1"}, "policy_") | ||||||
|  | 		mock.ExpectQuery("SELECT(.+)users(.+)"). | ||||||
|  | 			WillReturnRows(sqlmock.NewRows([]string{"id", "group_id"}).AddRow(1, 1)) | ||||||
|  | 		mock.ExpectQuery("SELECT(.+)groups(.+)"). | ||||||
|  | 			WillReturnRows(sqlmock.NewRows([]string{"id", "policies"}).AddRow(1, "[2]")) | ||||||
|  | 		mock.ExpectQuery("SELECT(.+)policies(.+)"). | ||||||
|  | 			WillReturnRows(sqlmock.NewRows([]string{"id", "access_key", "secret_key"}).AddRow(2, "123", "123")) | ||||||
|  | 		c, _ := gin.CreateTestContext(rec) | ||||||
|  | 		c.Params = []gin.Param{ | ||||||
|  | 			{"key", "testCallBackQiniu"}, | ||||||
|  | 		} | ||||||
|  | 		c.Request, _ = http.NewRequest("POST", "/api/v3/callback/qiniu/testCallBackQiniu", nil) | ||||||
|  | 		mac := qbox.NewMac("123", "123") | ||||||
|  | 		token, err := mac.SignRequest(c.Request) | ||||||
|  | 		asserts.NoError(err) | ||||||
|  | 		c.Request.Header["Authorization"] = []string{"QBox " + token} | ||||||
|  | 		AuthFunc(c) | ||||||
|  | 		asserts.NoError(mock.ExpectationsWereMet()) | ||||||
|  | 		asserts.False(c.IsAborted()) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// 验证失败 | ||||||
|  | 	{ | ||||||
|  | 		cache.Set( | ||||||
|  | 			"callback_testCallBackQiniu", | ||||||
|  | 			serializer.UploadSession{ | ||||||
|  | 				UID:         1, | ||||||
|  | 				PolicyID:    2, | ||||||
|  | 				VirtualPath: "/", | ||||||
|  | 			}, | ||||||
|  | 			0, | ||||||
|  | 		) | ||||||
|  | 		cache.Deletes([]string{"1"}, "policy_") | ||||||
|  | 		mock.ExpectQuery("SELECT(.+)users(.+)"). | ||||||
|  | 			WillReturnRows(sqlmock.NewRows([]string{"id", "group_id"}).AddRow(1, 1)) | ||||||
|  | 		mock.ExpectQuery("SELECT(.+)groups(.+)"). | ||||||
|  | 			WillReturnRows(sqlmock.NewRows([]string{"id", "policies"}).AddRow(1, "[2]")) | ||||||
|  | 		mock.ExpectQuery("SELECT(.+)policies(.+)"). | ||||||
|  | 			WillReturnRows(sqlmock.NewRows([]string{"id", "access_key", "secret_key"}).AddRow(2, "123", "123")) | ||||||
|  | 		c, _ := gin.CreateTestContext(rec) | ||||||
|  | 		c.Params = []gin.Param{ | ||||||
|  | 			{"key", "testCallBackQiniu"}, | ||||||
|  | 		} | ||||||
|  | 		c.Request, _ = http.NewRequest("POST", "/api/v3/callback/qiniu/testCallBackQiniu", nil) | ||||||
|  | 		mac := qbox.NewMac("123", "123") | ||||||
|  | 		token, err := mac.SignRequest(c.Request) | ||||||
|  | 		asserts.NoError(err) | ||||||
|  | 		c.Request.Header["Authorization"] = []string{"QBox " + token + " "} | ||||||
|  | 		AuthFunc(c) | ||||||
|  | 		asserts.NoError(mock.ExpectationsWereMet()) | ||||||
|  | 		asserts.True(c.IsAborted()) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | |||||||
| @ -164,3 +164,11 @@ func TestPolicy_GetUploadURL(t *testing.T) { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func TestPolicy_IsPathGenerateNeeded(t *testing.T) { | ||||||
|  | 	asserts := assert.New(t) | ||||||
|  | 	policy := Policy{Type: "qiniu"} | ||||||
|  | 	asserts.True(policy.IsPathGenerateNeeded()) | ||||||
|  | 	policy.Type = "remote" | ||||||
|  | 	asserts.False(policy.IsPathGenerateNeeded()) | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,38 +0,0 @@ | |||||||
| package qiniu |  | ||||||
|  |  | ||||||
| import ( |  | ||||||
| 	"io" |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| // FileStream 用户传来的文件 |  | ||||||
| type FileStream struct { |  | ||||||
| 	File        io.ReadCloser |  | ||||||
| 	Size        uint64 |  | ||||||
| 	VirtualPath string |  | ||||||
| 	Name        string |  | ||||||
| 	MIMEType    string |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (file FileStream) Read(p []byte) (n int, err error) { |  | ||||||
| 	return file.File.Read(p) |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (file FileStream) GetMIMEType() string { |  | ||||||
| 	return file.MIMEType |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (file FileStream) GetSize() uint64 { |  | ||||||
| 	return file.Size |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (file FileStream) Close() error { |  | ||||||
| 	return file.File.Close() |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (file FileStream) GetFileName() string { |  | ||||||
| 	return file.Name |  | ||||||
| } |  | ||||||
|  |  | ||||||
| func (file FileStream) GetVirtualPath() string { |  | ||||||
| 	return file.VirtualPath |  | ||||||
| } |  | ||||||
							
								
								
									
										42
									
								
								pkg/filesystem/qiniu/handler_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								pkg/filesystem/qiniu/handler_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | |||||||
|  | package qiniu | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	model "github.com/HFO4/cloudreve/models" | ||||||
|  | 	"github.com/HFO4/cloudreve/pkg/cache" | ||||||
|  | 	"github.com/HFO4/cloudreve/pkg/filesystem/fsctx" | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | 	"testing" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | func TestHandler_Token(t *testing.T) { | ||||||
|  | 	asserts := assert.New(t) | ||||||
|  | 	handler := Handler{ | ||||||
|  | 		Policy: &model.Policy{ | ||||||
|  | 			MaxSize: 10, | ||||||
|  | 			OptionsSerialized: model.PolicyOption{ | ||||||
|  | 				MimeType: "ss", | ||||||
|  | 			}, | ||||||
|  | 			AccessKey: "ak", | ||||||
|  | 			SecretKey: "sk", | ||||||
|  | 			Server:    "http://test.com", | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 	ctx := context.Background() | ||||||
|  |  | ||||||
|  | 	// 成功 | ||||||
|  | 	{ | ||||||
|  | 		cache.Set("setting_siteURL", "http://test.cloudreve.org", 0) | ||||||
|  | 		ctx = context.WithValue(ctx, fsctx.SavePathCtx, "/123") | ||||||
|  | 		_, err := handler.Token(ctx, 10, "123") | ||||||
|  | 		asserts.NoError(err) | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// 上下文无存储路径 | ||||||
|  | 	{ | ||||||
|  | 		ctx = context.Background() | ||||||
|  | 		cache.Set("setting_siteURL", "http://test.cloudreve.org", 0) | ||||||
|  | 		_, err := handler.Token(ctx, 10, "123") | ||||||
|  | 		asserts.Error(err) | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @ -3,12 +3,10 @@ package qiniu | |||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" |  | ||||||
| 	model "github.com/HFO4/cloudreve/models" | 	model "github.com/HFO4/cloudreve/models" | ||||||
| 	"github.com/HFO4/cloudreve/pkg/filesystem/fsctx" | 	"github.com/HFO4/cloudreve/pkg/filesystem/fsctx" | ||||||
| 	"github.com/HFO4/cloudreve/pkg/filesystem/response" | 	"github.com/HFO4/cloudreve/pkg/filesystem/response" | ||||||
| 	"github.com/HFO4/cloudreve/pkg/serializer" | 	"github.com/HFO4/cloudreve/pkg/serializer" | ||||||
| 	"github.com/qiniu/api.v7/v7/auth" |  | ||||||
| 	"github.com/qiniu/api.v7/v7/auth/qbox" | 	"github.com/qiniu/api.v7/v7/auth/qbox" | ||||||
| 	"github.com/qiniu/api.v7/v7/storage" | 	"github.com/qiniu/api.v7/v7/storage" | ||||||
| 	"io" | 	"io" | ||||||
| @ -28,31 +26,31 @@ func (handler Handler) Get(ctx context.Context, path string) (response.RSCloser, | |||||||
| // Put 将文件流保存到指定目录 | // Put 将文件流保存到指定目录 | ||||||
| func (handler Handler) Put(ctx context.Context, file io.ReadCloser, dst string, size uint64) error { | func (handler Handler) Put(ctx context.Context, file io.ReadCloser, dst string, size uint64) error { | ||||||
| 	return errors.New("未实现") | 	return errors.New("未实现") | ||||||
| 	// 凭证生成 | 	//// 凭证生成 | ||||||
| 	putPolicy := storage.PutPolicy{ | 	//putPolicy := storage.PutPolicy{ | ||||||
| 		Scope: "cloudrevetest", | 	//	Scope: "cloudrevetest", | ||||||
| 	} | 	//} | ||||||
| 	mac := auth.New("YNzTBBpDUq4EEiFV0-vyJCZCJ0LvUEI0_WvxtEXE", "Clm9d9M2CH7pZ8vm049ZlGZStQxrRQVRTjU_T5_0") | 	//mac := auth.New("YNzTBBpDUq4EEiFV0-vyJCZCJ0LvUEI0_WvxtEXE", "Clm9d9M2CH7pZ8vm049ZlGZStQxrRQVRTjU_T5_0") | ||||||
| 	upToken := putPolicy.UploadToken(mac) | 	//upToken := putPolicy.UploadToken(mac) | ||||||
|  | 	// | ||||||
| 	cfg := storage.Config{} | 	//cfg := storage.Config{} | ||||||
| 	// 空间对应的机房 | 	//// 空间对应的机房 | ||||||
| 	cfg.Zone = &storage.ZoneHuadong | 	//cfg.Zone = &storage.ZoneHuadong | ||||||
| 	formUploader := storage.NewFormUploader(&cfg) | 	//formUploader := storage.NewFormUploader(&cfg) | ||||||
| 	ret := storage.PutRet{} | 	//ret := storage.PutRet{} | ||||||
| 	putExtra := storage.PutExtra{ | 	//putExtra := storage.PutExtra{ | ||||||
| 		Params: map[string]string{}, | 	//	Params: map[string]string{}, | ||||||
| 	} | 	//} | ||||||
|  | 	// | ||||||
| 	defer file.Close() | 	//defer file.Close() | ||||||
|  | 	// | ||||||
| 	err := formUploader.Put(ctx, &ret, upToken, dst, file, int64(size), &putExtra) | 	//err := formUploader.Put(ctx, &ret, upToken, dst, file, int64(size), &putExtra) | ||||||
| 	if err != nil { | 	//if err != nil { | ||||||
| 		fmt.Println(err) | 	//	fmt.Println(err) | ||||||
| 		return err | 	//	return err | ||||||
| 	} | 	//} | ||||||
| 	fmt.Println(ret.Key, ret.Hash) | 	//fmt.Println(ret.Key, ret.Hash) | ||||||
| 	return nil | 	//return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // Delete 删除一个或多个文件, | // Delete 删除一个或多个文件, | ||||||
| @ -94,7 +92,6 @@ func (handler Handler) Token(ctx context.Context, TTL int64, key string) (serial | |||||||
| 	// 创建上传策略 | 	// 创建上传策略 | ||||||
| 	putPolicy := storage.PutPolicy{ | 	putPolicy := storage.PutPolicy{ | ||||||
| 		Scope:            handler.Policy.BucketName, | 		Scope:            handler.Policy.BucketName, | ||||||
| 		Expires:          uint64(TTL), |  | ||||||
| 		CallbackURL:      apiURL.String(), | 		CallbackURL:      apiURL.String(), | ||||||
| 		CallbackBody:     `{"name":"$(fname)","source_name":"$(key)","size":$(fsize),"pic_info":"$(imageInfo.width),$(imageInfo.height)"}`, | 		CallbackBody:     `{"name":"$(fname)","source_name":"$(key)","size":$(fsize),"pic_info":"$(imageInfo.width),$(imageInfo.height)"}`, | ||||||
| 		CallbackBodyType: "application/json", | 		CallbackBodyType: "application/json", | ||||||
| @ -107,8 +104,14 @@ func (handler Handler) Token(ctx context.Context, TTL int64, key string) (serial | |||||||
| 		putPolicy.MimeLimit = handler.Policy.OptionsSerialized.MimeType | 		putPolicy.MimeLimit = handler.Policy.OptionsSerialized.MimeType | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	return handler.getUploadCredential(ctx, putPolicy, TTL) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // getUploadCredential 签名上传策略 | ||||||
|  | func (handler Handler) getUploadCredential(ctx context.Context, policy storage.PutPolicy, TTL int64) (serializer.UploadCredential, error) { | ||||||
|  | 	policy.Expires = uint64(TTL) | ||||||
| 	mac := qbox.NewMac(handler.Policy.AccessKey, handler.Policy.SecretKey) | 	mac := qbox.NewMac(handler.Policy.AccessKey, handler.Policy.SecretKey) | ||||||
| 	upToken := putPolicy.UploadToken(mac) | 	upToken := policy.UploadToken(mac) | ||||||
|  |  | ||||||
| 	return serializer.UploadCredential{ | 	return serializer.UploadCredential{ | ||||||
| 		Token: upToken, | 		Token: upToken, | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 HFO4
					HFO4