Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

protected_tag.go 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package models
  5. import (
  6. "regexp"
  7. "strings"
  8. "code.gitea.io/gitea/models/db"
  9. "code.gitea.io/gitea/modules/base"
  10. "code.gitea.io/gitea/modules/timeutil"
  11. "github.com/gobwas/glob"
  12. )
  13. // ProtectedTag struct
  14. type ProtectedTag struct {
  15. ID int64 `xorm:"pk autoincr"`
  16. RepoID int64
  17. NamePattern string
  18. RegexPattern *regexp.Regexp `xorm:"-"`
  19. GlobPattern glob.Glob `xorm:"-"`
  20. AllowlistUserIDs []int64 `xorm:"JSON TEXT"`
  21. AllowlistTeamIDs []int64 `xorm:"JSON TEXT"`
  22. CreatedUnix timeutil.TimeStamp `xorm:"created"`
  23. UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
  24. }
  25. func init() {
  26. db.RegisterModel(new(ProtectedTag))
  27. }
  28. // InsertProtectedTag inserts a protected tag to database
  29. func InsertProtectedTag(pt *ProtectedTag) error {
  30. _, err := db.GetEngine(db.DefaultContext).Insert(pt)
  31. return err
  32. }
  33. // UpdateProtectedTag updates the protected tag
  34. func UpdateProtectedTag(pt *ProtectedTag) error {
  35. _, err := db.GetEngine(db.DefaultContext).ID(pt.ID).AllCols().Update(pt)
  36. return err
  37. }
  38. // DeleteProtectedTag deletes a protected tag by ID
  39. func DeleteProtectedTag(pt *ProtectedTag) error {
  40. _, err := db.GetEngine(db.DefaultContext).ID(pt.ID).Delete(&ProtectedTag{})
  41. return err
  42. }
  43. // EnsureCompiledPattern ensures the glob pattern is compiled
  44. func (pt *ProtectedTag) EnsureCompiledPattern() error {
  45. if pt.RegexPattern != nil || pt.GlobPattern != nil {
  46. return nil
  47. }
  48. var err error
  49. if len(pt.NamePattern) >= 2 && strings.HasPrefix(pt.NamePattern, "/") && strings.HasSuffix(pt.NamePattern, "/") {
  50. pt.RegexPattern, err = regexp.Compile(pt.NamePattern[1 : len(pt.NamePattern)-1])
  51. } else {
  52. pt.GlobPattern, err = glob.Compile(pt.NamePattern)
  53. }
  54. return err
  55. }
  56. // IsUserAllowed returns true if the user is allowed to modify the tag
  57. func (pt *ProtectedTag) IsUserAllowed(userID int64) (bool, error) {
  58. if base.Int64sContains(pt.AllowlistUserIDs, userID) {
  59. return true, nil
  60. }
  61. if len(pt.AllowlistTeamIDs) == 0 {
  62. return false, nil
  63. }
  64. in, err := IsUserInTeams(userID, pt.AllowlistTeamIDs)
  65. if err != nil {
  66. return false, err
  67. }
  68. return in, nil
  69. }
  70. // GetProtectedTags gets all protected tags of the repository
  71. func (repo *Repository) GetProtectedTags() ([]*ProtectedTag, error) {
  72. tags := make([]*ProtectedTag, 0)
  73. return tags, db.GetEngine(db.DefaultContext).Find(&tags, &ProtectedTag{RepoID: repo.ID})
  74. }
  75. // GetProtectedTagByID gets the protected tag with the specific id
  76. func GetProtectedTagByID(id int64) (*ProtectedTag, error) {
  77. tag := new(ProtectedTag)
  78. has, err := db.GetEngine(db.DefaultContext).ID(id).Get(tag)
  79. if err != nil {
  80. return nil, err
  81. }
  82. if !has {
  83. return nil, nil
  84. }
  85. return tag, nil
  86. }
  87. // IsUserAllowedToControlTag checks if a user can control the specific tag.
  88. // It returns true if the tag name is not protected or the user is allowed to control it.
  89. func IsUserAllowedToControlTag(tags []*ProtectedTag, tagName string, userID int64) (bool, error) {
  90. isAllowed := true
  91. for _, tag := range tags {
  92. err := tag.EnsureCompiledPattern()
  93. if err != nil {
  94. return false, err
  95. }
  96. if !tag.matchString(tagName) {
  97. continue
  98. }
  99. isAllowed, err = tag.IsUserAllowed(userID)
  100. if err != nil {
  101. return false, err
  102. }
  103. if isAllowed {
  104. break
  105. }
  106. }
  107. return isAllowed, nil
  108. }
  109. func (pt *ProtectedTag) matchString(name string) bool {
  110. if pt.RegexPattern != nil {
  111. return pt.RegexPattern.MatchString(name)
  112. }
  113. return pt.GlobPattern.Match(name)
  114. }