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

metadata.go 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Copyright 2023 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package chef
  4. import (
  5. "archive/tar"
  6. "compress/gzip"
  7. "io"
  8. "regexp"
  9. "strings"
  10. "code.gitea.io/gitea/modules/json"
  11. "code.gitea.io/gitea/modules/util"
  12. "code.gitea.io/gitea/modules/validation"
  13. )
  14. const (
  15. KeyBits = 4096
  16. SettingPublicPem = "chef.public_pem"
  17. )
  18. var (
  19. ErrMissingMetadataFile = util.NewInvalidArgumentErrorf("metadata.json file is missing")
  20. ErrInvalidName = util.NewInvalidArgumentErrorf("package name is invalid")
  21. ErrInvalidVersion = util.NewInvalidArgumentErrorf("package version is invalid")
  22. namePattern = regexp.MustCompile(`\A\S+\z`)
  23. versionPattern = regexp.MustCompile(`\A\d+\.\d+(?:\.\d+)?\z`)
  24. )
  25. // Package represents a Chef package
  26. type Package struct {
  27. Name string
  28. Version string
  29. Metadata *Metadata
  30. }
  31. // Metadata represents the metadata of a Chef package
  32. type Metadata struct {
  33. Description string `json:"description,omitempty"`
  34. LongDescription string `json:"long_description,omitempty"`
  35. Author string `json:"author,omitempty"`
  36. License string `json:"license,omitempty"`
  37. RepositoryURL string `json:"repository_url,omitempty"`
  38. Dependencies map[string]string `json:"dependencies,omitempty"`
  39. }
  40. type chefMetadata struct {
  41. Name string `json:"name"`
  42. Description string `json:"description"`
  43. LongDescription string `json:"long_description"`
  44. Maintainer string `json:"maintainer"`
  45. MaintainerEmail string `json:"maintainer_email"`
  46. License string `json:"license"`
  47. Platforms map[string]string `json:"platforms"`
  48. Dependencies map[string]string `json:"dependencies"`
  49. Providing map[string]string `json:"providing"`
  50. Recipes map[string]string `json:"recipes"`
  51. Version string `json:"version"`
  52. SourceURL string `json:"source_url"`
  53. IssuesURL string `json:"issues_url"`
  54. Privacy bool `json:"privacy"`
  55. ChefVersions [][]string `json:"chef_versions"`
  56. Gems [][]string `json:"gems"`
  57. EagerLoadLibraries bool `json:"eager_load_libraries"`
  58. }
  59. // ParsePackage parses the Chef package file
  60. func ParsePackage(r io.Reader) (*Package, error) {
  61. gzr, err := gzip.NewReader(r)
  62. if err != nil {
  63. return nil, err
  64. }
  65. defer gzr.Close()
  66. tr := tar.NewReader(gzr)
  67. for {
  68. hd, err := tr.Next()
  69. if err == io.EOF {
  70. break
  71. }
  72. if err != nil {
  73. return nil, err
  74. }
  75. if hd.Typeflag != tar.TypeReg {
  76. continue
  77. }
  78. if strings.Count(hd.Name, "/") != 1 {
  79. continue
  80. }
  81. if hd.FileInfo().Name() == "metadata.json" {
  82. return ParseChefMetadata(tr)
  83. }
  84. }
  85. return nil, ErrMissingMetadataFile
  86. }
  87. // ParseChefMetadata parses a metadata.json file to retrieve the metadata of a Chef package
  88. func ParseChefMetadata(r io.Reader) (*Package, error) {
  89. var cm chefMetadata
  90. if err := json.NewDecoder(r).Decode(&cm); err != nil {
  91. return nil, err
  92. }
  93. if !namePattern.MatchString(cm.Name) {
  94. return nil, ErrInvalidName
  95. }
  96. if !versionPattern.MatchString(cm.Version) {
  97. return nil, ErrInvalidVersion
  98. }
  99. if !validation.IsValidURL(cm.SourceURL) {
  100. cm.SourceURL = ""
  101. }
  102. return &Package{
  103. Name: cm.Name,
  104. Version: cm.Version,
  105. Metadata: &Metadata{
  106. Description: cm.Description,
  107. LongDescription: cm.LongDescription,
  108. Author: cm.Maintainer,
  109. License: cm.License,
  110. RepositoryURL: cm.SourceURL,
  111. Dependencies: cm.Dependencies,
  112. },
  113. }, nil
  114. }