You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

efile.go 2.5 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package efile
  2. import (
  3. "fmt"
  4. "net/url"
  5. "sync"
  6. "time"
  7. "gitlink.org.cn/cloudream/common/utils/http2"
  8. "gitlink.org.cn/cloudream/common/utils/serder"
  9. clitypes "gitlink.org.cn/cloudream/storage2/client/types"
  10. "gitlink.org.cn/cloudream/storage2/common/pkgs/storage/factory/reg"
  11. "gitlink.org.cn/cloudream/storage2/common/pkgs/storage/types"
  12. "gitlink.org.cn/cloudream/storage2/common/pkgs/storage/utils"
  13. cortypes "gitlink.org.cn/cloudream/storage2/coordinator/types"
  14. )
  15. func init() {
  16. reg.RegisterBuilder[*cortypes.EFileType](func(detail *clitypes.UserSpaceDetail) types.StorageBuilder {
  17. return &builder{
  18. detail: detail,
  19. }
  20. })
  21. }
  22. type builder struct {
  23. types.EmptyBuilder
  24. detail *clitypes.UserSpaceDetail
  25. token string
  26. tokenLock sync.Mutex
  27. getTokenTime time.Time
  28. }
  29. func (b *builder) getToken() (string, error) {
  30. cred := b.detail.UserSpace.Credential.(*cortypes.EFileCred)
  31. b.tokenLock.Lock()
  32. defer b.tokenLock.Unlock()
  33. if b.token != "" {
  34. dt := time.Since(b.getTokenTime)
  35. if dt < time.Second*time.Duration(cred.TokenExpire) {
  36. return b.token, nil
  37. }
  38. }
  39. u, err := url.JoinPath(cred.TokenURL, "/ac/openapi/v2/tokens")
  40. if err != nil {
  41. return "", err
  42. }
  43. resp, err := http2.PostJSON(u, http2.RequestParam{
  44. Header: map[string]string{
  45. "user": cred.User,
  46. "password": cred.Password,
  47. "orgId": cred.OrgID,
  48. },
  49. })
  50. if err != nil {
  51. return "", err
  52. }
  53. type Response struct {
  54. Code string `json:"code"`
  55. Msg string `json:"msg"`
  56. Data []struct {
  57. ClusterID string `json:"clusterId"`
  58. Token string `json:"token"`
  59. } `json:"data"`
  60. }
  61. var r Response
  62. err = serder.JSONToObjectStream(resp.Body, &r)
  63. if err != nil {
  64. return "", err
  65. }
  66. if r.Code != "0" {
  67. return "", fmt.Errorf("code:%s, msg:%s", r.Code, r.Msg)
  68. }
  69. for _, d := range r.Data {
  70. if d.ClusterID == cred.ClusterID {
  71. b.token = d.Token
  72. b.getTokenTime = time.Now()
  73. return d.Token, nil
  74. }
  75. }
  76. return "", fmt.Errorf("clusterID %s not found", cred.ClusterID)
  77. }
  78. func (b *builder) CreateECMultiplier() (types.ECMultiplier, error) {
  79. feat := utils.FindFeature[*cortypes.ECMultiplierFeature](b.detail.Storage)
  80. if feat == nil {
  81. return nil, fmt.Errorf("feature ECMultiplier not found")
  82. }
  83. cred, ok := b.detail.UserSpace.Credential.(*cortypes.EFileCred)
  84. if !ok {
  85. return nil, fmt.Errorf("invalid storage credential type %T for efile storage", b.detail.UserSpace.Credential)
  86. }
  87. return &ECMultiplier{
  88. blder: b,
  89. url: cred.APIURL,
  90. feat: feat,
  91. }, nil
  92. }

本项目旨在将云际存储公共基础设施化,使个人及企业可低门槛使用高效的云际存储服务(安装开箱即用云际存储客户端即可,无需关注其他组件的部署),同时支持用户灵活便捷定制云际存储的功能细节。