mirror of
				https://github.com/cloudreve/cloudreve.git
				synced 2025-10-31 16:49:03 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			171 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			171 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package admin
 | |
| 
 | |
| import (
 | |
| 	"encoding/hex"
 | |
| 	"net/http"
 | |
| 	"strconv"
 | |
| 
 | |
| 	"github.com/cloudreve/Cloudreve/v4/application/dependency"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/pkg/boolset"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/manager"
 | |
| 	request2 "github.com/cloudreve/Cloudreve/v4/pkg/request"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/pkg/serializer"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/pkg/setting"
 | |
| 	"github.com/cloudreve/Cloudreve/v4/pkg/wopi"
 | |
| 	"github.com/gin-gonic/gin"
 | |
| 	"github.com/go-mail/mail"
 | |
| )
 | |
| 
 | |
| type (
 | |
| 	HashIDService struct {
 | |
| 		ID     int    `json:"id"`
 | |
| 		Type   int    `json:"type"`
 | |
| 		HashID string `json:"hash_id"`
 | |
| 	}
 | |
| 	HashIDParamCtx struct{}
 | |
| )
 | |
| 
 | |
| func (service *HashIDService) Encode(c *gin.Context) (string, error) {
 | |
| 	dep := dependency.FromContext(c)
 | |
| 	res, err := dep.HashIDEncoder().Encode([]int{service.ID, service.Type})
 | |
| 	if err != nil {
 | |
| 		return "", err
 | |
| 	}
 | |
| 	return res, nil
 | |
| }
 | |
| 
 | |
| func (service *HashIDService) Decode(c *gin.Context) (int, error) {
 | |
| 	dep := dependency.FromContext(c)
 | |
| 	res, err := dep.HashIDEncoder().Decode(service.HashID, service.Type)
 | |
| 	if err != nil {
 | |
| 		return 0, err
 | |
| 	}
 | |
| 
 | |
| 	return res, nil
 | |
| }
 | |
| 
 | |
| type (
 | |
| 	BsEncodeService struct {
 | |
| 		Bool []int `json:"bool"`
 | |
| 	}
 | |
| 	BsEncodeParamCtx struct{}
 | |
| 	BsEncodeRes      struct {
 | |
| 		Hex string
 | |
| 		B64 []byte
 | |
| 	}
 | |
| )
 | |
| 
 | |
| func (service *BsEncodeService) Encode(c *gin.Context) (*BsEncodeRes, error) {
 | |
| 	bs := &boolset.BooleanSet{}
 | |
| 	for _, v := range service.Bool {
 | |
| 		boolset.Set(v, true, bs)
 | |
| 	}
 | |
| 
 | |
| 	res, err := bs.MarshalBinary()
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	return &BsEncodeRes{
 | |
| 		Hex: hex.EncodeToString(res),
 | |
| 		B64: res,
 | |
| 	}, nil
 | |
| }
 | |
| 
 | |
| type (
 | |
| 	BsDecodeService struct {
 | |
| 		Code string `json:"code"`
 | |
| 	}
 | |
| 	BsDecodeParamCtx struct{}
 | |
| 	BsDecodeRes      struct {
 | |
| 		Bool []int `json:"bool"`
 | |
| 	}
 | |
| )
 | |
| 
 | |
| func (service *BsDecodeService) Decode(c *gin.Context) (*BsDecodeRes, error) {
 | |
| 	bs, err := boolset.FromString(service.Code)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	res := []int{}
 | |
| 	for i := 0; i < len(*bs)*8; i++ {
 | |
| 		if bs.Enabled(i) {
 | |
| 			res = append(res, i)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return &BsDecodeRes{
 | |
| 		Bool: res,
 | |
| 	}, nil
 | |
| }
 | |
| 
 | |
| type (
 | |
| 	FetchWOPIDiscoveryService struct {
 | |
| 		Endpoint string `form:"endpoint" binding:"required"`
 | |
| 	}
 | |
| 	FetchWOPIDiscoveryParamCtx struct{}
 | |
| )
 | |
| 
 | |
| func (s *FetchWOPIDiscoveryService) Fetch(c *gin.Context) (*setting.ViewerGroup, error) {
 | |
| 	dep := dependency.FromContext(c)
 | |
| 	requestClient := dep.RequestClient(request2.WithContext(c), request2.WithLogger(dep.Logger()))
 | |
| 	content, err := requestClient.Request("GET", s.Endpoint, nil).CheckHTTPResponse(http.StatusOK).GetResponse()
 | |
| 	if err != nil {
 | |
| 		return nil, serializer.NewError(serializer.CodeInternalSetting, "WOPI endpoint id unavailable", err)
 | |
| 	}
 | |
| 
 | |
| 	vg, err := wopi.DiscoveryXmlToViewerGroup(content)
 | |
| 	if err != nil {
 | |
| 		return nil, serializer.NewError(serializer.CodeParamErr, "Failed to parse WOPI response", err)
 | |
| 	}
 | |
| 
 | |
| 	return vg, nil
 | |
| }
 | |
| 
 | |
| type (
 | |
| 	TestSMTPService struct {
 | |
| 		Settings map[string]string `json:"settings" binding:"required"`
 | |
| 		To       string            `json:"to" binding:"required,email"`
 | |
| 	}
 | |
| 	TestSMTPParamCtx struct{}
 | |
| )
 | |
| 
 | |
| func (s *TestSMTPService) Test(c *gin.Context) error {
 | |
| 	port, err := strconv.Atoi(s.Settings["smtpPort"])
 | |
| 	if err != nil {
 | |
| 		return serializer.NewError(serializer.CodeParamErr, "Invalid SMTP port", err)
 | |
| 	}
 | |
| 
 | |
| 	d := mail.NewDialer(s.Settings["smtpHost"], port, s.Settings["smtpUser"], s.Settings["smtpPass"])
 | |
| 	d.SSL = false
 | |
| 	if setting.IsTrueValue(s.Settings["smtpEncryption"]) {
 | |
| 		d.SSL = true
 | |
| 	}
 | |
| 	d.StartTLSPolicy = mail.OpportunisticStartTLS
 | |
| 
 | |
| 	sender, err := d.Dial()
 | |
| 	if err != nil {
 | |
| 		return serializer.NewError(serializer.CodeInternalSetting, "Failed to connect to SMTP server: "+err.Error(), err)
 | |
| 	}
 | |
| 
 | |
| 	m := mail.NewMessage()
 | |
| 	m.SetHeader("From", s.Settings["fromAdress"])
 | |
| 	m.SetAddressHeader("Reply-To", s.Settings["replyTo"], s.Settings["fromName"])
 | |
| 	m.SetHeader("To", s.To)
 | |
| 	m.SetHeader("Subject", "Cloudreve SMTP Test")
 | |
| 	m.SetBody("text/plain", "This is a test email from Cloudreve.")
 | |
| 
 | |
| 	err = mail.Send(sender, m)
 | |
| 	if err != nil {
 | |
| 		return serializer.NewError(serializer.CodeInternalSetting, "Failed to send test email: "+err.Error(), err)
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func ClearEntityUrlCache(c *gin.Context) {
 | |
| 	dep := dependency.FromContext(c)
 | |
| 	dep.KV().Delete(manager.EntityUrlCacheKeyPrefix)
 | |
| }
 | 
