mirror of
https://github.com/IceWhaleTech/CasaOS.git
synced 2025-12-23 13:04:42 +00:00
Compare commits
10 Commits
v0.4.4-alp
...
v0.4.5-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b93209aac | ||
|
|
9e05dae154 | ||
|
|
1cd5c92a4c | ||
|
|
9d6381d7ac | ||
|
|
e5b172627a | ||
|
|
bbbb3b2f29 | ||
|
|
1453eac570 | ||
|
|
c649b67c20 | ||
|
|
93262dc549 | ||
|
|
a106abc8ba |
4
.github/workflows/push_test_server.yml
vendored
4
.github/workflows/push_test_server.yml
vendored
@@ -2,7 +2,7 @@ name: Auto Publish Website
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- community
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
jobs:
|
jobs:
|
||||||
@@ -19,7 +19,7 @@ jobs:
|
|||||||
- name: git global
|
- name: git global
|
||||||
run: sudo git config --global --add safe.directory '*'
|
run: sudo git config --global --add safe.directory '*'
|
||||||
- name: set version
|
- name: set version
|
||||||
run: sudo git tag v99.99.99-alpha
|
run: sudo git tag v00.00.00-alpha
|
||||||
|
|
||||||
- name: Fetch all tags
|
- name: Fetch all tags
|
||||||
run: sudo git fetch --force --tags
|
run: sudo git fetch --force --tags
|
||||||
|
|||||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -38,7 +38,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
# either 'goreleaser' (default) or 'goreleaser-pro'
|
# either 'goreleaser' (default) or 'goreleaser-pro'
|
||||||
distribution: goreleaser
|
distribution: goreleaser
|
||||||
version: latest
|
version: 1.14.1
|
||||||
args: release --rm-dist
|
args: release --rm-dist
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|||||||
@@ -19,6 +19,12 @@ builds:
|
|||||||
ldflags:
|
ldflags:
|
||||||
- -X main.commit={{.Commit}}
|
- -X main.commit={{.Commit}}
|
||||||
- -X main.date={{.Date}}
|
- -X main.date={{.Date}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_id={{.Env.GoogleID}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_secret={{.Env.GoogleSecret}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_id={{.Env.OneDreiveID}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_secret={{.Env.OneDeriveSecret}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_key={{.Env.DropboxKey}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_secret={{.Env.DropboxSecret}}
|
||||||
- -s
|
- -s
|
||||||
- -w
|
- -w
|
||||||
- -extldflags "-static"
|
- -extldflags "-static"
|
||||||
@@ -40,6 +46,12 @@ builds:
|
|||||||
ldflags:
|
ldflags:
|
||||||
- -X main.commit={{.Commit}}
|
- -X main.commit={{.Commit}}
|
||||||
- -X main.date={{.Date}}
|
- -X main.date={{.Date}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_id={{.Env.GoogleID}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_secret={{.Env.GoogleSecret}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_id={{.Env.OneDreiveID}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_secret={{.Env.OneDeriveSecret}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_key={{.Env.DropboxKey}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_secret={{.Env.DropboxSecret}}
|
||||||
- -s
|
- -s
|
||||||
- -w
|
- -w
|
||||||
- -extldflags "-static"
|
- -extldflags "-static"
|
||||||
@@ -61,6 +73,12 @@ builds:
|
|||||||
ldflags:
|
ldflags:
|
||||||
- -X main.commit={{.Commit}}
|
- -X main.commit={{.Commit}}
|
||||||
- -X main.date={{.Date}}
|
- -X main.date={{.Date}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_id={{.Env.GoogleID}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/google_drive.client_secret={{.Env.GoogleSecret}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_id={{.Env.OneDreiveID}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/onedrive.client_secret={{.Env.OneDeriveSecret}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_key={{.Env.DropboxKey}}
|
||||||
|
- -X github.com/IceWhaleTech/CasaOS/drivers/dropbox.app_secret={{.Env.DropboxSecret}}
|
||||||
- -s
|
- -s
|
||||||
- -w
|
- -w
|
||||||
- -extldflags "-static"
|
- -extldflags "-static"
|
||||||
@@ -143,24 +161,22 @@ builds:
|
|||||||
goarm:
|
goarm:
|
||||||
- "7"
|
- "7"
|
||||||
archives:
|
archives:
|
||||||
- name_template: "{{ .Os }}-{{ .Arch }}-{{ .ProjectName }}-v{{ .Version }}"
|
- name_template: >-
|
||||||
|
{{ .Os }}-{{- if eq .Arch "arm" }}arm-7{{- else }}{{ .Arch }}{{- end }}-{{ .ProjectName }}-v{{ .Version }}
|
||||||
id: casaos
|
id: casaos
|
||||||
builds:
|
builds:
|
||||||
- casaos-amd64
|
- casaos-amd64
|
||||||
- casaos-arm64
|
- casaos-arm64
|
||||||
- casaos-arm-7
|
- casaos-arm-7
|
||||||
replacements:
|
|
||||||
arm: arm-7
|
|
||||||
files:
|
files:
|
||||||
- build/**/*
|
- build/**/*
|
||||||
- name_template: "{{ .Os }}-{{ .Arch }}-{{ .ProjectName }}-migration-tool-v{{ .Version }}"
|
- name_template: >-
|
||||||
|
{{ .Os }}-{{- if eq .Arch "arm" }}arm-7{{- else }}{{ .Arch }}{{- end }}-{{ .ProjectName }}-migration-tool-v{{ .Version }}
|
||||||
id: casaos-migration-tool
|
id: casaos-migration-tool
|
||||||
builds:
|
builds:
|
||||||
- casaos-migration-tool-amd64
|
- casaos-migration-tool-amd64
|
||||||
- casaos-migration-tool-arm64
|
- casaos-migration-tool-arm64
|
||||||
- casaos-migration-tool-arm-7
|
- casaos-migration-tool-arm-7
|
||||||
replacements:
|
|
||||||
arm: arm-7
|
|
||||||
files:
|
files:
|
||||||
- build/sysroot/etc/**/*
|
- build/sysroot/etc/**/*
|
||||||
checksum:
|
checksum:
|
||||||
|
|||||||
@@ -60,6 +60,22 @@ paths:
|
|||||||
"500":
|
"500":
|
||||||
$ref: "#/components/responses/ResponseInternalServerError"
|
$ref: "#/components/responses/ResponseInternalServerError"
|
||||||
|
|
||||||
|
/health/logs:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Health methods
|
||||||
|
summary: Get log
|
||||||
|
operationId: getHealthlogs
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/octet-stream:
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: binary
|
||||||
|
"500":
|
||||||
|
$ref: "#/components/responses/ResponseInternalServerError"
|
||||||
/file/test:
|
/file/test:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
|
|||||||
@@ -65,6 +65,9 @@ type ServerInterface interface {
|
|||||||
// Test file methods
|
// Test file methods
|
||||||
// (GET /file/test)
|
// (GET /file/test)
|
||||||
GetFileTest(ctx echo.Context) error
|
GetFileTest(ctx echo.Context) error
|
||||||
|
// Get log
|
||||||
|
// (GET /health/logs)
|
||||||
|
GetHealthlogs(ctx echo.Context) error
|
||||||
// Get port in use
|
// Get port in use
|
||||||
// (GET /health/ports)
|
// (GET /health/ports)
|
||||||
GetHealthPorts(ctx echo.Context) error
|
GetHealthPorts(ctx echo.Context) error
|
||||||
@@ -89,6 +92,17 @@ func (w *ServerInterfaceWrapper) GetFileTest(ctx echo.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetHealthlogs converts echo context to params.
|
||||||
|
func (w *ServerInterfaceWrapper) GetHealthlogs(ctx echo.Context) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx.Set(Access_tokenScopes, []string{""})
|
||||||
|
|
||||||
|
// Invoke the callback with all the unmarshalled arguments
|
||||||
|
err = w.Handler.GetHealthlogs(ctx)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// GetHealthPorts converts echo context to params.
|
// GetHealthPorts converts echo context to params.
|
||||||
func (w *ServerInterfaceWrapper) GetHealthPorts(ctx echo.Context) error {
|
func (w *ServerInterfaceWrapper) GetHealthPorts(ctx echo.Context) error {
|
||||||
var err error
|
var err error
|
||||||
@@ -140,6 +154,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
|
|||||||
}
|
}
|
||||||
|
|
||||||
router.GET(baseURL+"/file/test", wrapper.GetFileTest)
|
router.GET(baseURL+"/file/test", wrapper.GetFileTest)
|
||||||
|
router.GET(baseURL+"/health/logs", wrapper.GetHealthlogs)
|
||||||
router.GET(baseURL+"/health/ports", wrapper.GetHealthPorts)
|
router.GET(baseURL+"/health/ports", wrapper.GetHealthPorts)
|
||||||
router.GET(baseURL+"/health/services", wrapper.GetHealthServices)
|
router.GET(baseURL+"/health/services", wrapper.GetHealthServices)
|
||||||
|
|
||||||
@@ -148,24 +163,25 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
|
|||||||
// Base64 encoded, gzipped, json marshaled Swagger object
|
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||||
var swaggerSpec = []string{
|
var swaggerSpec = []string{
|
||||||
|
|
||||||
"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",
|
||||||
"BwAA///xoj5w+wwAAA==",
|
"p31/kOFAD7/r+pPL6ZvpyXbA2IkeflQcv3DvTQiBbkasijN0je/i9ed+2XtN9oRet38HAAD///s5WXsj",
|
||||||
|
"DgAA",
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSwagger returns the content of the embedded swagger specification file
|
// GetSwagger returns the content of the embedded swagger specification file
|
||||||
|
|||||||
@@ -2,6 +2,6 @@ package common
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
SERVICENAME = "casaos"
|
SERVICENAME = "casaos"
|
||||||
VERSION = "0.4.4"
|
VERSION = "0.4.4.1"
|
||||||
BODY = " "
|
BODY = " "
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package drivers
|
|||||||
import (
|
import (
|
||||||
_ "github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
_ "github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
||||||
_ "github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
_ "github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
||||||
|
_ "github.com/IceWhaleTech/CasaOS/drivers/onedrive"
|
||||||
)
|
)
|
||||||
|
|
||||||
// All do nothing,just for import
|
// All do nothing,just for import
|
||||||
|
|||||||
@@ -96,5 +96,8 @@ func (d *Dropbox) Remove(ctx context.Context, obj model.Obj) error {
|
|||||||
func (d *Dropbox) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
func (d *Dropbox) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
func (d *Dropbox) GetInfo(ctx context.Context) (string, string, string, error) {
|
||||||
|
return "", "", "", nil
|
||||||
|
}
|
||||||
|
|
||||||
var _ driver.Driver = (*Dropbox)(nil)
|
var _ driver.Driver = (*Dropbox)(nil)
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const ICONURL = "./img/driver/Dropbox.svg"
|
const ICONURL = "./img/driver/Dropbox.svg"
|
||||||
const APPKEY = "tciqajyazzdygt9"
|
|
||||||
const APPSECRET = "e7gtmv441cwdf0n"
|
|
||||||
|
|
||||||
type Addition struct {
|
type Addition struct {
|
||||||
driver.RootID
|
driver.RootID
|
||||||
@@ -15,7 +13,7 @@ type Addition struct {
|
|||||||
AppKey string `json:"app_key" type:"string" default:"tciqajyazzdygt9" omit:"true"`
|
AppKey string `json:"app_key" type:"string" default:"tciqajyazzdygt9" omit:"true"`
|
||||||
AppSecret string `json:"app_secret" type:"string" default:"e7gtmv441cwdf0n" omit:"true"`
|
AppSecret string `json:"app_secret" type:"string" default:"e7gtmv441cwdf0n" omit:"true"`
|
||||||
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" omit:"true"`
|
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" omit:"true"`
|
||||||
AuthUrl string `json:"auth_url" type:"string" default:"https://www.dropbox.com/oauth2/authorize?client_id=tciqajyazzdygt9&redirect_uri=https://cloudoauth.files.casaos.app&response_type=code&token_access_type=offline&state=${HOST}%2Fv1%2Frecover%2FDropbox&&force_reapprove=true&force_reauthentication=true"`
|
AuthUrl string `json:"auth_url" type:"string" default:""`
|
||||||
Icon string `json:"icon" type:"string" default:"./img/driver/Dropbox.svg"`
|
Icon string `json:"icon" type:"string" default:"./img/driver/Dropbox.svg"`
|
||||||
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
||||||
}
|
}
|
||||||
@@ -28,6 +26,7 @@ var config = driver.Config{
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
op.RegisterDriver(func() driver.Driver {
|
op.RegisterDriver(func() driver.Driver {
|
||||||
return &Dropbox{}
|
dropbox := GetConfig()
|
||||||
|
return &dropbox
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ import (
|
|||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
app_key = "private build"
|
||||||
|
app_secret = "private build"
|
||||||
|
)
|
||||||
|
|
||||||
func (d *Dropbox) getRefreshToken() error {
|
func (d *Dropbox) getRefreshToken() error {
|
||||||
url := "https://api.dropbox.com/oauth2/token"
|
url := "https://api.dropbox.com/oauth2/token"
|
||||||
var resp base.TokenResp
|
var resp base.TokenResp
|
||||||
@@ -100,3 +105,12 @@ func (d *Dropbox) getFiles(path string) ([]File, error) {
|
|||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
func GetConfig() Dropbox {
|
||||||
|
dp := Dropbox{}
|
||||||
|
dp.RootFolderID = ""
|
||||||
|
dp.AuthUrl = "https://www.dropbox.com/oauth2/authorize?client_id=" + app_key + "&redirect_uri=https://cloudoauth.files.casaos.app&response_type=code&token_access_type=offline&state=${HOST}%2Fv2%2Frecover%2FDropbox&&force_reapprove=true&force_reauthentication=true"
|
||||||
|
dp.AppKey = app_key
|
||||||
|
dp.AppSecret = app_secret
|
||||||
|
dp.Icon = "./img/driver/Dropbox.svg"
|
||||||
|
return dp
|
||||||
|
}
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ func (d *GoogleDrive) GetUserInfo(ctx context.Context) (string, error) {
|
|||||||
return user.User.EmailAddress, nil
|
return user.User.EmailAddress, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *GoogleDrive) GetInfo(ctx context.Context) (string, string, string, error) {
|
||||||
|
return "", "", "", nil
|
||||||
|
}
|
||||||
func (d *GoogleDrive) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
func (d *GoogleDrive) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) error {
|
||||||
data := base.Json{
|
data := base.Json{
|
||||||
"name": dirName,
|
"name": dirName,
|
||||||
|
|||||||
@@ -6,18 +6,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const ICONURL = "./img/driver/GoogleDrive.svg"
|
const ICONURL = "./img/driver/GoogleDrive.svg"
|
||||||
const CLIENTID = "921743327851-urr4f7jjfp4ts639evqb3i4m4qb4u4cc.apps.googleusercontent.com"
|
|
||||||
const CLIENTSECRET = "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"
|
|
||||||
|
|
||||||
type Addition struct {
|
type Addition struct {
|
||||||
driver.RootID
|
driver.RootID
|
||||||
RefreshToken string `json:"refresh_token" required:"true" omit:"true"`
|
RefreshToken string `json:"refresh_token" required:"true" omit:"true"`
|
||||||
OrderBy string `json:"order_by" type:"string" help:"such as: folder,name,modifiedTime" omit:"true"`
|
OrderBy string `json:"order_by" type:"string" help:"such as: folder,name,modifiedTime" omit:"true"`
|
||||||
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" omit:"true"`
|
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" omit:"true"`
|
||||||
ClientID string `json:"client_id" required:"true" default:"921743327851-urr4f7jjfp4ts639evqb3i4m4qb4u4cc.apps.googleusercontent.com" omit:"true"`
|
ClientID string `json:"client_id" required:"true" default:"" omit:"true"`
|
||||||
ClientSecret string `json:"client_secret" required:"true" default:"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" omit:"true"`
|
ClientSecret string `json:"client_secret" required:"true" default:"" omit:"true"`
|
||||||
ChunkSize int64 `json:"chunk_size" type:"number" help:"chunk size while uploading (unit: MB)" omit:"true"`
|
ChunkSize int64 `json:"chunk_size" type:"number" help:"chunk size while uploading (unit: MB)" omit:"true"`
|
||||||
AuthUrl string `json:"auth_url" type:"string" default:"https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?response_type=code&client_id=921743327851-urr4f7jjfp4ts639evqb3i4m4qb4u4cc.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fcloudoauth.files.casaos.app&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&access_type=offline&approval_prompt=force&state=${HOST}%2Fv1%2Frecover%2FGoogleDrive&service=lso&o2v=1&flowName=GeneralOAuthFlow"`
|
AuthUrl string `json:"auth_url" type:"string" default:""`
|
||||||
Icon string `json:"icon" type:"string" default:"./img/driver/GoogleDrive.svg"`
|
Icon string `json:"icon" type:"string" default:"./img/driver/GoogleDrive.svg"`
|
||||||
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
||||||
}
|
}
|
||||||
@@ -30,6 +28,7 @@ var config = driver.Config{
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
op.RegisterDriver(func() driver.Driver {
|
op.RegisterDriver(func() driver.Driver {
|
||||||
return &GoogleDrive{}
|
google := GetConfig()
|
||||||
|
return &google
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ import (
|
|||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
client_id = "private build"
|
||||||
|
client_secret = "private build"
|
||||||
|
)
|
||||||
|
|
||||||
// do others that not defined in Driver interface
|
// do others that not defined in Driver interface
|
||||||
|
|
||||||
func (d *GoogleDrive) getRefreshToken() error {
|
func (d *GoogleDrive) getRefreshToken() error {
|
||||||
@@ -150,3 +155,13 @@ func (d *GoogleDrive) chunkUpload(ctx context.Context, stream model.FileStreamer
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
func GetConfig() GoogleDrive {
|
||||||
|
config := GoogleDrive{}
|
||||||
|
config.ClientID = client_id
|
||||||
|
config.ClientSecret = client_secret
|
||||||
|
config.RootFolderID = "root"
|
||||||
|
config.AuthUrl = "https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?response_type=code&client_id=" + client_id + "&redirect_uri=https%3A%2F%2Fcloudoauth.files.casaos.app&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&access_type=offline&approval_prompt=force&state=${HOST}%2Fv2%2Frecover%2FGoogleDrive&service=lso&o2v=1&flowName=GeneralOAuthFlow"
|
||||||
|
config.Icon = "./img/driver/GoogleDrive.svg"
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|||||||
70
drivers/onedrive/drive.go
Normal file
70
drivers/onedrive/drive.go
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
package onedrive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/model"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Onedrive struct {
|
||||||
|
model.StorageA
|
||||||
|
Addition
|
||||||
|
AccessToken string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Onedrive) Config() driver.Config {
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Onedrive) GetAddition() driver.Additional {
|
||||||
|
return &d.Addition
|
||||||
|
}
|
||||||
|
func (d *Onedrive) Init(ctx context.Context) error {
|
||||||
|
if d.ChunkSize < 1 {
|
||||||
|
d.ChunkSize = 5
|
||||||
|
}
|
||||||
|
if len(d.RefreshToken) == 0 {
|
||||||
|
return d.getRefreshToken()
|
||||||
|
}
|
||||||
|
return d.refreshToken()
|
||||||
|
}
|
||||||
|
func (d *Onedrive) GetUserInfo(ctx context.Context) (string, error) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
func (d *Onedrive) GetInfo(ctx context.Context) (string, string, string, error) {
|
||||||
|
url := d.GetMetaUrl(false, "/")
|
||||||
|
user := Info{}
|
||||||
|
resp, err := d.Request(url, http.MethodGet, nil, &user)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.Info("resp", zap.Any("resp", resp))
|
||||||
|
return user.LastModifiedBy.User.DisplayName, user.ParentReference.DriveID, user.ParentReference.DriveType, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Onedrive) GetSpaceSize(ctx context.Context) (used string, total string, err error) {
|
||||||
|
host := onedriveHostMap[d.Region]
|
||||||
|
url := fmt.Sprintf("%s/v1.0/me/drive/quota", host.Api)
|
||||||
|
size := About{}
|
||||||
|
resp, err := d.Request(url, http.MethodGet, nil, &size)
|
||||||
|
if err != nil {
|
||||||
|
return used, total, err
|
||||||
|
}
|
||||||
|
logger.Info("resp", zap.Any("resp", resp))
|
||||||
|
used = strconv.Itoa(size.Used)
|
||||||
|
total = strconv.Itoa(size.Total)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func (d *Onedrive) Drop(ctx context.Context) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ driver.Driver = (*Onedrive)(nil)
|
||||||
75
drivers/onedrive/meta.go
Normal file
75
drivers/onedrive/meta.go
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
package onedrive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/IceWhaleTech/CasaOS/internal/driver"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/internal/op"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Host struct {
|
||||||
|
Oauth string
|
||||||
|
Api string
|
||||||
|
}
|
||||||
|
|
||||||
|
type TokenErr struct {
|
||||||
|
Error string `json:"error"`
|
||||||
|
ErrorDescription string `json:"error_description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RespErr struct {
|
||||||
|
Error struct {
|
||||||
|
Code string `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
} `json:"error"`
|
||||||
|
}
|
||||||
|
type Addition struct {
|
||||||
|
Region string `json:"region" type:"select" required:"true" options:"global,cn,us,de" default:"global"`
|
||||||
|
IsSharepoint bool `json:"is_sharepoint"`
|
||||||
|
ClientID string `json:"client_id" required:"true"`
|
||||||
|
ClientSecret string `json:"client_secret" required:"true"`
|
||||||
|
RedirectUri string `json:"redirect_uri" required:"true" default:""`
|
||||||
|
RefreshToken string `json:"refresh_token" required:"true"`
|
||||||
|
SiteId string `json:"site_id"`
|
||||||
|
ChunkSize int64 `json:"chunk_size" type:"number" default:"5"`
|
||||||
|
RootFolderID string `json:"root_folder_id"`
|
||||||
|
AuthUrl string `json:"auth_url" type:"string" default:""`
|
||||||
|
Icon string `json:"icon" type:"string" default:""`
|
||||||
|
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
||||||
|
}
|
||||||
|
type About struct {
|
||||||
|
Total int `json:"total"`
|
||||||
|
Used int `json:"used"`
|
||||||
|
State string `json:"state"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Info struct {
|
||||||
|
LastModifiedBy struct {
|
||||||
|
Application struct {
|
||||||
|
DisplayName string `json:"displayName"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
} `json:"application"`
|
||||||
|
Device struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
} `json:"device"`
|
||||||
|
User struct {
|
||||||
|
DisplayName string `json:"displayName"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
} `json:"user"`
|
||||||
|
} `json:"lastModifiedBy"`
|
||||||
|
ParentReference struct {
|
||||||
|
DriveID string `json:"driveId"`
|
||||||
|
DriveType string `json:"driveType"`
|
||||||
|
} `json:"parentReference"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var config = driver.Config{
|
||||||
|
Name: "Onedrive",
|
||||||
|
LocalSort: true,
|
||||||
|
DefaultRoot: "/",
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
op.RegisterDriver(func() driver.Driver {
|
||||||
|
one := GetConfig()
|
||||||
|
return &one
|
||||||
|
})
|
||||||
|
}
|
||||||
183
drivers/onedrive/util.go
Normal file
183
drivers/onedrive/util.go
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
package onedrive
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/drivers/base"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
client_id = "private build"
|
||||||
|
|
||||||
|
client_secret = "private build"
|
||||||
|
)
|
||||||
|
var onedriveHostMap = map[string]Host{
|
||||||
|
"global": {
|
||||||
|
Oauth: "https://login.microsoftonline.com",
|
||||||
|
Api: "https://graph.microsoft.com",
|
||||||
|
},
|
||||||
|
"cn": {
|
||||||
|
Oauth: "https://login.chinacloudapi.cn",
|
||||||
|
Api: "https://microsoftgraph.chinacloudapi.cn",
|
||||||
|
},
|
||||||
|
"us": {
|
||||||
|
Oauth: "https://login.microsoftonline.us",
|
||||||
|
Api: "https://graph.microsoft.us",
|
||||||
|
},
|
||||||
|
"de": {
|
||||||
|
Oauth: "https://login.microsoftonline.de",
|
||||||
|
Api: "https://graph.microsoft.de",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func EncodePath(path string, all ...bool) string {
|
||||||
|
seg := strings.Split(path, "/")
|
||||||
|
toReplace := []struct {
|
||||||
|
Src string
|
||||||
|
Dst string
|
||||||
|
}{
|
||||||
|
{Src: "%", Dst: "%25"},
|
||||||
|
{"%", "%25"},
|
||||||
|
{"?", "%3F"},
|
||||||
|
{"#", "%23"},
|
||||||
|
}
|
||||||
|
for i := range seg {
|
||||||
|
if len(all) > 0 && all[0] {
|
||||||
|
seg[i] = url.PathEscape(seg[i])
|
||||||
|
} else {
|
||||||
|
for j := range toReplace {
|
||||||
|
seg[i] = strings.ReplaceAll(seg[i], toReplace[j].Src, toReplace[j].Dst)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(seg, "/")
|
||||||
|
}
|
||||||
|
func (d *Onedrive) GetMetaUrl(auth bool, path string) string {
|
||||||
|
host := onedriveHostMap[d.Region]
|
||||||
|
path = EncodePath(path, true)
|
||||||
|
if auth {
|
||||||
|
return host.Oauth
|
||||||
|
}
|
||||||
|
if d.IsSharepoint {
|
||||||
|
if path == "/" || path == "\\" {
|
||||||
|
return fmt.Sprintf("%s/v1.0/sites/%s/drive/root", host.Api, d.SiteId)
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("%s/v1.0/sites/%s/drive/root:%s:", host.Api, d.SiteId, path)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if path == "/" || path == "\\" {
|
||||||
|
return fmt.Sprintf("%s/v1.0/me/drive/root", host.Api)
|
||||||
|
} else {
|
||||||
|
return fmt.Sprintf("%s/v1.0/me/drive/root:%s:", host.Api, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Onedrive) refreshToken() error {
|
||||||
|
var err error
|
||||||
|
for i := 0; i < 3; i++ {
|
||||||
|
err = d._refreshToken()
|
||||||
|
if err == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Onedrive) getRefreshToken() error {
|
||||||
|
url := d.GetMetaUrl(true, "") + "/common/oauth2/v2.0/token"
|
||||||
|
var resp base.TokenResp
|
||||||
|
var e TokenErr
|
||||||
|
|
||||||
|
res, err := base.RestyClient.R().SetResult(&resp).SetError(&e).SetFormData(map[string]string{
|
||||||
|
"grant_type": "authorization_code",
|
||||||
|
"client_id": d.ClientID,
|
||||||
|
"client_secret": d.ClientSecret,
|
||||||
|
"code": d.Code,
|
||||||
|
"redirect_uri": d.RedirectUri,
|
||||||
|
}).Post(url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logger.Info("get refresh token", zap.String("res", res.String()))
|
||||||
|
if e.Error != "" {
|
||||||
|
return fmt.Errorf("%s", e.ErrorDescription)
|
||||||
|
}
|
||||||
|
if resp.RefreshToken == "" {
|
||||||
|
return errors.New("refresh token is empty")
|
||||||
|
}
|
||||||
|
d.RefreshToken, d.AccessToken = resp.RefreshToken, resp.AccessToken
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Onedrive) _refreshToken() error {
|
||||||
|
url := d.GetMetaUrl(true, "") + "/common/oauth2/v2.0/token"
|
||||||
|
var resp base.TokenResp
|
||||||
|
var e TokenErr
|
||||||
|
|
||||||
|
res, err := base.RestyClient.R().SetResult(&resp).SetError(&e).SetFormData(map[string]string{
|
||||||
|
"grant_type": "refresh_token",
|
||||||
|
"client_id": d.ClientID,
|
||||||
|
"client_secret": d.ClientSecret,
|
||||||
|
"redirect_uri": d.RedirectUri,
|
||||||
|
"refresh_token": d.RefreshToken,
|
||||||
|
}).Post(url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
logger.Info("get refresh token", zap.String("res", res.String()))
|
||||||
|
if e.Error != "" {
|
||||||
|
return fmt.Errorf("%s", e.ErrorDescription)
|
||||||
|
}
|
||||||
|
if resp.RefreshToken == "" {
|
||||||
|
return errors.New("refresh token is empty")
|
||||||
|
}
|
||||||
|
d.RefreshToken, d.AccessToken = resp.RefreshToken, resp.AccessToken
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Onedrive) Request(url string, method string, callback base.ReqCallback, resp interface{}) ([]byte, error) {
|
||||||
|
req := base.RestyClient.R()
|
||||||
|
req.SetHeader("Authorization", "Bearer "+d.AccessToken)
|
||||||
|
if callback != nil {
|
||||||
|
callback(req)
|
||||||
|
}
|
||||||
|
if resp != nil {
|
||||||
|
req.SetResult(resp)
|
||||||
|
}
|
||||||
|
var e RespErr
|
||||||
|
req.SetError(&e)
|
||||||
|
res, err := req.Execute(method, url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if e.Error.Code != "" {
|
||||||
|
if e.Error.Code == "InvalidAuthenticationToken" {
|
||||||
|
err = d.refreshToken()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return d.Request(url, method, callback, resp)
|
||||||
|
}
|
||||||
|
return nil, errors.New(e.Error.Message)
|
||||||
|
}
|
||||||
|
return res.Body(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetConfig() Onedrive {
|
||||||
|
config := Onedrive{}
|
||||||
|
config.ClientID = client_id
|
||||||
|
config.ClientSecret = client_secret
|
||||||
|
config.RootFolderID = "/"
|
||||||
|
config.AuthUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" + client_id + "&response_type=code&redirect_uri=http%3A%2F%2Flocalhost%2Fcallback&scope=offline_access+files.readwrite.all&state=${HOST}%2Fv2%2Frecover%2FOnedrive"
|
||||||
|
config.Icon = "./img/driver/OneDrive.svg"
|
||||||
|
config.Region = "global"
|
||||||
|
config.RedirectUri = "https://cloudoauth.files.casaos.app"
|
||||||
|
|
||||||
|
return config
|
||||||
|
}
|
||||||
@@ -34,14 +34,16 @@ type Reader interface {
|
|||||||
// List files in the path
|
// List files in the path
|
||||||
// if identify files by path, need to set ID with path,like path.Join(dir.GetID(), obj.GetName())
|
// if identify files by path, need to set ID with path,like path.Join(dir.GetID(), obj.GetName())
|
||||||
// if identify files by id, need to set ID with corresponding id
|
// if identify files by id, need to set ID with corresponding id
|
||||||
List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error)
|
// List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error)
|
||||||
// Link get url/filepath/reader of file
|
// Link get url/filepath/reader of file
|
||||||
Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error)
|
// Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error)
|
||||||
}
|
}
|
||||||
type User interface {
|
type User interface {
|
||||||
// GetRoot get root directory of user
|
// GetRoot get root directory of user
|
||||||
GetUserInfo(ctx context.Context) (string, error)
|
GetUserInfo(ctx context.Context) (string, error)
|
||||||
|
GetInfo(ctx context.Context) (string, string, string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Getter interface {
|
type Getter interface {
|
||||||
GetRoot(ctx context.Context) (model.Obj, error)
|
GetRoot(ctx context.Context) (model.Obj, error)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -431,7 +431,9 @@ func AddFile(ar archiver.Writer, path, commonPath string) error {
|
|||||||
defer file.Close()
|
defer file.Close()
|
||||||
|
|
||||||
if path != commonPath {
|
if path != commonPath {
|
||||||
filename := info.Name()
|
//filename := info.Name()
|
||||||
|
filename := strings.TrimPrefix(path, commonPath)
|
||||||
|
filename = strings.TrimPrefix(filename, string(filepath.Separator))
|
||||||
err = ar.Write(archiver.File{
|
err = ar.Write(archiver.File{
|
||||||
FileInfo: archiver.FileInfo{
|
FileInfo: archiver.FileInfo{
|
||||||
FileInfo: info,
|
FileInfo: info,
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
"github.com/IceWhaleTech/CasaOS-Common/utils/logger"
|
||||||
"github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
"github.com/IceWhaleTech/CasaOS/drivers/dropbox"
|
||||||
"github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
"github.com/IceWhaleTech/CasaOS/drivers/google_drive"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/drivers/onedrive"
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
@@ -20,23 +21,17 @@ func GetRecoverStorage(c *gin.Context) {
|
|||||||
currentDate := time.Now().UTC().Format("2006-01-02")
|
currentDate := time.Now().UTC().Format("2006-01-02")
|
||||||
notify := make(map[string]interface{})
|
notify := make(map[string]interface{})
|
||||||
if t == "GoogleDrive" {
|
if t == "GoogleDrive" {
|
||||||
add := google_drive.Addition{}
|
google_drive := google_drive.GetConfig()
|
||||||
add.Code = c.Query("code")
|
google_drive.Code = c.Query("code")
|
||||||
if len(add.Code) == 0 {
|
if len(google_drive.Code) == 0 {
|
||||||
c.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`)
|
c.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`)
|
||||||
notify["status"] = "fail"
|
notify["status"] = "fail"
|
||||||
notify["message"] = "Code cannot be empty"
|
notify["message"] = "Code cannot be empty"
|
||||||
logger.Error("Then code is empty: ", zap.String("code", add.Code), zap.Any("name", "google_drive"))
|
logger.Error("Then code is empty: ", zap.String("code", google_drive.Code), zap.Any("name", "google_drive"))
|
||||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
add.RootFolderID = "root"
|
|
||||||
add.ClientID = google_drive.CLIENTID
|
|
||||||
add.ClientSecret = google_drive.CLIENTSECRET
|
|
||||||
|
|
||||||
var google_drive google_drive.GoogleDrive
|
|
||||||
google_drive.Addition = add
|
|
||||||
err := google_drive.Init(c)
|
err := google_drive.Init(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
|
c.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
|
||||||
@@ -93,8 +88,8 @@ func GetRecoverStorage(c *gin.Context) {
|
|||||||
//username = fileutil.NameAccumulation(username, "/mnt")
|
//username = fileutil.NameAccumulation(username, "/mnt")
|
||||||
username += "_google_drive_" + strconv.FormatInt(time.Now().Unix(), 10)
|
username += "_google_drive_" + strconv.FormatInt(time.Now().Unix(), 10)
|
||||||
|
|
||||||
dmap["client_id"] = add.ClientID
|
dmap["client_id"] = google_drive.ClientID
|
||||||
dmap["client_secret"] = add.ClientSecret
|
dmap["client_secret"] = google_drive.ClientSecret
|
||||||
dmap["scope"] = "drive"
|
dmap["scope"] = "drive"
|
||||||
dmap["mount_point"] = "/mnt/" + username
|
dmap["mount_point"] = "/mnt/" + username
|
||||||
dmap["token"] = `{"access_token":"` + google_drive.AccessToken + `","token_type":"Bearer","refresh_token":"` + google_drive.RefreshToken + `","expiry":"` + currentDate + `T` + currentTime.Add(time.Hour*1).Add(time.Minute*50).Format("15:04:05") + `Z"}`
|
dmap["token"] = `{"access_token":"` + google_drive.AccessToken + `","token_type":"Bearer","refresh_token":"` + google_drive.RefreshToken + `","expiry":"` + currentDate + `T` + currentTime.Add(time.Hour*1).Add(time.Minute*50).Format("15:04:05") + `Z"}`
|
||||||
@@ -106,21 +101,17 @@ func GetRecoverStorage(c *gin.Context) {
|
|||||||
notify["driver"] = "GoogleDrive"
|
notify["driver"] = "GoogleDrive"
|
||||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
} else if t == "Dropbox" {
|
} else if t == "Dropbox" {
|
||||||
add := dropbox.Addition{}
|
dropbox := dropbox.GetConfig()
|
||||||
add.Code = c.Query("code")
|
dropbox.Code = c.Query("code")
|
||||||
if len(add.Code) == 0 {
|
if len(dropbox.Code) == 0 {
|
||||||
c.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`)
|
c.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`)
|
||||||
notify["status"] = "fail"
|
notify["status"] = "fail"
|
||||||
notify["message"] = "Code cannot be empty"
|
notify["message"] = "Code cannot be empty"
|
||||||
logger.Error("Then code is empty error: ", zap.String("code", add.Code), zap.Any("name", "dropbox"))
|
logger.Error("Then code is empty error: ", zap.String("code", dropbox.Code), zap.Any("name", "dropbox"))
|
||||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
add.RootFolderID = ""
|
|
||||||
add.AppKey = dropbox.APPKEY
|
|
||||||
add.AppSecret = dropbox.APPSECRET
|
|
||||||
var dropbox dropbox.Dropbox
|
|
||||||
dropbox.Addition = add
|
|
||||||
err := dropbox.Init(c)
|
err := dropbox.Init(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
|
c.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
|
||||||
@@ -176,8 +167,8 @@ func GetRecoverStorage(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
username += "_dropbox_" + strconv.FormatInt(time.Now().Unix(), 10)
|
username += "_dropbox_" + strconv.FormatInt(time.Now().Unix(), 10)
|
||||||
|
|
||||||
dmap["client_id"] = add.AppKey
|
dmap["client_id"] = dropbox.AppKey
|
||||||
dmap["client_secret"] = add.AppSecret
|
dmap["client_secret"] = dropbox.AppSecret
|
||||||
dmap["token"] = `{"access_token":"` + dropbox.AccessToken + `","token_type":"bearer","refresh_token":"` + dropbox.Addition.RefreshToken + `","expiry":"` + currentDate + `T` + currentTime.Add(time.Hour*3).Add(time.Minute*50).Format("15:04:05") + `.780385354Z"}`
|
dmap["token"] = `{"access_token":"` + dropbox.AccessToken + `","token_type":"bearer","refresh_token":"` + dropbox.Addition.RefreshToken + `","expiry":"` + currentDate + `T` + currentTime.Add(time.Hour*3).Add(time.Minute*50).Format("15:04:05") + `.780385354Z"}`
|
||||||
dmap["mount_point"] = "/mnt/" + username
|
dmap["mount_point"] = "/mnt/" + username
|
||||||
// data.SetValue(username, "type", "dropbox")
|
// data.SetValue(username, "type", "dropbox")
|
||||||
@@ -199,6 +190,98 @@ func GetRecoverStorage(c *gin.Context) {
|
|||||||
notify["message"] = "Success"
|
notify["message"] = "Success"
|
||||||
notify["driver"] = "Dropbox"
|
notify["driver"] = "Dropbox"
|
||||||
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
|
} else if t == "Onedrive" {
|
||||||
|
onedrive := onedrive.GetConfig()
|
||||||
|
onedrive.Code = c.Query("code")
|
||||||
|
if len(onedrive.Code) == 0 {
|
||||||
|
c.String(200, `<p>Code cannot be empty</p><script>window.close()</script>`)
|
||||||
|
notify["status"] = "fail"
|
||||||
|
notify["message"] = "Code cannot be empty"
|
||||||
|
logger.Error("Then code is empty error: ", zap.String("code", onedrive.Code), zap.Any("name", "onedrive"))
|
||||||
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := onedrive.Init(c)
|
||||||
|
if err != nil {
|
||||||
|
c.String(200, `<p>Initialization failure:`+err.Error()+`</p><script>window.close()</script>`)
|
||||||
|
notify["status"] = "fail"
|
||||||
|
notify["message"] = "Initialization failure"
|
||||||
|
logger.Error("Then init error: ", zap.Error(err), zap.Any("name", "onedrive"))
|
||||||
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
username, driveId, driveType, err := onedrive.GetInfo(c)
|
||||||
|
if err != nil {
|
||||||
|
c.String(200, `<p>Failed to get user information:`+err.Error()+`</p><script>window.close()</script>`)
|
||||||
|
notify["status"] = "fail"
|
||||||
|
notify["message"] = "Failed to get user information"
|
||||||
|
logger.Error("Then get user information: ", zap.Error(err), zap.Any("name", "onedrive"))
|
||||||
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
dmap := make(map[string]string)
|
||||||
|
dmap["username"] = username
|
||||||
|
|
||||||
|
configs, err := service.MyService.Storage().GetConfig()
|
||||||
|
if err != nil {
|
||||||
|
c.String(200, `<p>Failed to get rclone config:`+err.Error()+`</p><script>window.close()</script>`)
|
||||||
|
notify["status"] = "fail"
|
||||||
|
notify["message"] = "Failed to get rclone config"
|
||||||
|
logger.Error("Then get config error: ", zap.Error(err), zap.Any("name", "onedrive"))
|
||||||
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, v := range configs.Remotes {
|
||||||
|
cf, err := service.MyService.Storage().GetConfigByName(v)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("then get config by name error: ", zap.Error(err), zap.Any("name", v))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if cf["type"] == "onedrive" && cf["username"] == dmap["username"] {
|
||||||
|
c.String(200, `<p>The same configuration has been added</p><script>window.close()</script>`)
|
||||||
|
err := service.MyService.Storage().CheckAndMountByName(v)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("check and mount by name error: ", zap.Error(err), zap.Any("name", cf["username"]))
|
||||||
|
}
|
||||||
|
|
||||||
|
notify["status"] = "warn"
|
||||||
|
notify["message"] = "The same configuration has been added"
|
||||||
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(username) > 0 {
|
||||||
|
a := strings.Split(username, "@")
|
||||||
|
username = a[0]
|
||||||
|
}
|
||||||
|
username += "_dropbox_" + strconv.FormatInt(time.Now().Unix(), 10)
|
||||||
|
|
||||||
|
dmap["client_id"] = onedrive.ClientID
|
||||||
|
dmap["client_secret"] = onedrive.ClientSecret
|
||||||
|
dmap["token"] = `{"access_token":"` + onedrive.AccessToken + `","token_type":"bearer","refresh_token":"` + onedrive.RefreshToken + `","expiry":"` + currentDate + `T` + currentTime.Add(time.Hour*3).Add(time.Minute*50).Format("15:04:05") + `.780385354Z"}`
|
||||||
|
dmap["mount_point"] = "/mnt/" + username
|
||||||
|
dmap["drive_id"] = driveId
|
||||||
|
dmap["drive_type"] = driveType
|
||||||
|
// data.SetValue(username, "type", "dropbox")
|
||||||
|
// data.SetValue(username, "client_id", add.AppKey)
|
||||||
|
// data.SetValue(username, "client_secret", add.AppSecret)
|
||||||
|
// data.SetValue(username, "mount_point", "/mnt/"+username)
|
||||||
|
|
||||||
|
// data.SetValue(username, "token", `{"access_token":"`+dropbox.AccessToken+`","token_type":"bearer","refresh_token":"`+dropbox.Addition.RefreshToken+`","expiry":"`+currentDate+`T`+currentTime.Add(time.Hour*3).Format("15:04:05")+`.780385354Z"}`)
|
||||||
|
// e = data.Save()
|
||||||
|
// if e != nil {
|
||||||
|
// c.String(200, `<p>保存配置失败:`+e.Error()+`</p>`)
|
||||||
|
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
service.MyService.Storage().CreateConfig(dmap, username, "onedrive")
|
||||||
|
service.MyService.Storage().MountStorage("/mnt/"+username, username+":")
|
||||||
|
|
||||||
|
notify["status"] = "success"
|
||||||
|
notify["message"] = "Success"
|
||||||
|
notify["driver"] = "Onedrive"
|
||||||
|
service.MyService.Notify().SendNotify("casaos:file:recover", notify)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.String(200, `<p>Just close the page</p><script>window.close()</script>`)
|
c.String(200, `<p>Just close the page</p><script>window.close()</script>`)
|
||||||
|
|||||||
36
route/v2.go
36
route/v2.go
@@ -90,7 +90,10 @@ func InitV2Router() http.Handler {
|
|||||||
},
|
},
|
||||||
TokenLookupFuncs: []echo_middleware.ValuesExtractor{
|
TokenLookupFuncs: []echo_middleware.ValuesExtractor{
|
||||||
func(c echo.Context) ([]string, error) {
|
func(c echo.Context) ([]string, error) {
|
||||||
return []string{c.Request().Header.Get(echo.HeaderAuthorization)}, nil
|
if len(c.Request().Header.Get(echo.HeaderAuthorization)) > 0 {
|
||||||
|
return []string{c.Request().Header.Get(echo.HeaderAuthorization)}, nil
|
||||||
|
}
|
||||||
|
return []string{c.QueryParam("token")}, nil
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
@@ -145,15 +148,46 @@ func InitV2DocRouter(docHTML string, docYAML string) http.Handler {
|
|||||||
|
|
||||||
func InitFile() http.Handler {
|
func InitFile() http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
token := r.URL.Query().Get("token")
|
||||||
|
if len(token) == 0 {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
w.Write([]byte(`{"message": "token not found"}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
valid, _, errs := jwt.Validate(token, func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) })
|
||||||
|
if errs != nil || !valid {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
w.Write([]byte(`{"message": "validation failure"}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
filePath := r.URL.Query().Get("path")
|
filePath := r.URL.Query().Get("path")
|
||||||
fileName := path.Base(filePath)
|
fileName := path.Base(filePath)
|
||||||
w.Header().Add("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(fileName))
|
w.Header().Add("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(fileName))
|
||||||
http.ServeFile(w, r, filePath)
|
http.ServeFile(w, r, filePath)
|
||||||
|
//http.ServeFile(w, r, filePath)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitDir() http.Handler {
|
func InitDir() http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
token := r.URL.Query().Get("token")
|
||||||
|
if len(token) == 0 {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
w.Write([]byte(`{"message": "token not found"}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
valid, _, errs := jwt.Validate(token, func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) })
|
||||||
|
if errs != nil || !valid {
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
w.Write([]byte(`{"message": "validation failure"}`))
|
||||||
|
return
|
||||||
|
}
|
||||||
t := r.URL.Query().Get("format")
|
t := r.URL.Query().Get("format")
|
||||||
files := r.URL.Query().Get("files")
|
files := r.URL.Query().Get("files")
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,15 @@ package v2
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/IceWhaleTech/CasaOS/codegen"
|
"github.com/IceWhaleTech/CasaOS/codegen"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||||
"github.com/IceWhaleTech/CasaOS/service"
|
"github.com/IceWhaleTech/CasaOS/service"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/mholt/archiver/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *CasaOS) GetHealthServices(ctx echo.Context) error {
|
func (s *CasaOS) GetHealthServices(ctx echo.Context) error {
|
||||||
@@ -41,3 +46,55 @@ func (s *CasaOS) GetHealthPorts(ctx echo.Context) error {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
func (c *CasaOS) GetHealthlogs(ctx echo.Context) error {
|
||||||
|
var name, currentPath, commonDir, extension string
|
||||||
|
var err error
|
||||||
|
var ar archiver.Writer
|
||||||
|
fileList, err := os.ReadDir("/var/log/casaos")
|
||||||
|
if err != nil {
|
||||||
|
message := err.Error()
|
||||||
|
return ctx.JSON(http.StatusInternalServerError, codegen.ResponseInternalServerError{
|
||||||
|
Message: &message,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
extension, ar, err = file.GetCompressionAlgorithm("zip")
|
||||||
|
if err != nil {
|
||||||
|
ctx.Response().Header().Set("Content-Type", "application/json")
|
||||||
|
message := err.Error()
|
||||||
|
return ctx.JSON(http.StatusNotFound, codegen.ResponseInternalServerError{
|
||||||
|
Message: &message,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
err = ar.Create(ctx.Response().Writer)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Response().Header().Set("Content-Type", "application/json")
|
||||||
|
message := err.Error()
|
||||||
|
return ctx.JSON(http.StatusNotFound, codegen.ResponseInternalServerError{
|
||||||
|
Message: &message,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
defer ar.Close()
|
||||||
|
|
||||||
|
commonDir = "/var/log/casaos"
|
||||||
|
|
||||||
|
currentPath = filepath.Base(commonDir)
|
||||||
|
|
||||||
|
name = currentPath
|
||||||
|
name += extension
|
||||||
|
ctx.Response().Header().Add("Content-Type", "application/octet-stream")
|
||||||
|
ctx.Response().Header().Add("Content-Transfer-Encoding", "binary")
|
||||||
|
ctx.Response().Header().Add("Cache-Control", "no-cache")
|
||||||
|
ctx.Response().Header().Add("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(name))
|
||||||
|
|
||||||
|
for _, fname := range fileList {
|
||||||
|
err := file.AddFile(ar, filepath.Join("/var/log/casaos", fname.Name()), commonDir)
|
||||||
|
if err != nil {
|
||||||
|
message := err.Error()
|
||||||
|
return ctx.JSON(http.StatusInternalServerError, codegen.ResponseInternalServerError{
|
||||||
|
Message: &message,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user