Skip to content

Commit

Permalink
Added topics validation, fixed repo topics duplication (go-gitea#4031)
Browse files Browse the repository at this point in the history
Signed-off-by: Alexey Terentyev <axifnx@gmail.com>
  • Loading branch information
axifive committed Jun 16, 2018
1 parent 85414d8 commit 42096c6
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 2 deletions.
23 changes: 23 additions & 0 deletions models/topic.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"code.gitea.io/gitea/modules/util"

"github.com/go-xorm/builder"
"regexp"
)

func init() {
Expand All @@ -20,6 +21,8 @@ func init() {
)
}

var topicPattern = regexp.MustCompile(`^[a-z0-9+#_.-]+$`)

// Topic represents a topic of repositories
type Topic struct {
ID int64
Expand Down Expand Up @@ -51,6 +54,26 @@ func (err ErrTopicNotExist) Error() string {
return fmt.Sprintf("topic is not exist [name: %s]", err.Name)
}

func TopicValidator(topic string) bool {
return len(topic) <= 35 && topicPattern.MatchString(topic)
}

// Remove duplicates from topics slice
func RemoveDuplicateTopics(topics []string) []string {
// Map to record duplicates
saved := make(map[string]struct{}, len(topics))
i := 0
for _, v := range topics {
v = strings.TrimSpace(strings.ToLower(v))
if _, ok := saved[v]; !ok {
saved[v] = struct{}{}
topics[i] = v
i++
}
}
return topics[:i]
}

// GetTopicByName retrieves topic by name
func GetTopicByName(name string) (*Topic, error) {
var topic Topic
Expand Down
2 changes: 2 additions & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1167,6 +1167,8 @@ branch.protected_deletion_failed = Branch '%s' is protected. It cannot be delete

topic.manage_topics = Manage Topics
topic.done = Done
topic.count_prompt = You can't select more than 25 topics
topic.format_prompt = Topics must use letter or number and can include hyphen(-), underscore(_), plus(+), hash(#), dot(.) with max length of 35
[org]
org_name_holder = Organization Name
Expand Down
29 changes: 28 additions & 1 deletion routers/repo/topic.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

// TopicPost response for creating repository
func TopicPost(ctx *context.Context) {
func TopicsPost(ctx *context.Context) {
if ctx.User == nil {
ctx.JSON(403, map[string]interface{}{
"message": "Only owners could change the topics.",
Expand All @@ -27,6 +27,33 @@ func TopicPost(ctx *context.Context) {
topics = strings.Split(topicsStr, ",")
}

topics = models.RemoveDuplicateTopics(topics)

if len(topics) > 25 {
log.Error(2, "Incorrect number of topics(max 25): %v", )
ctx.JSON(422, map[string]interface{}{
"invalidTopics": topics[:0],
"message": ctx.Tr("repo.topic.count_error"),
})
return
}

var invalidTopics = make([]string, 0)
for _, topic := range topics {
if !models.TopicValidator(topic) {
invalidTopics = append(invalidTopics, topic)
}
}

if len(invalidTopics) > 0 {
log.Error(2, "Invalid topics: %v", invalidTopics)
ctx.JSON(422, map[string]interface{}{
"invalidTopics": invalidTopics,
"message": ctx.Tr("repo.topic.pattern_error"),
})
return
}

err := models.SaveTopics(ctx.Repo.Repository.ID, topics...)
if err != nil {
log.Error(2, "SaveTopics failed: %v", err)
Expand Down
2 changes: 1 addition & 1 deletion routers/routes/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ func RegisterRoutes(m *macaron.Macaron) {
}, context.RepoAssignment(), context.UnitTypes(), context.LoadRepoUnits(), context.CheckUnit(models.UnitTypeReleases))

m.Group("/:username/:reponame", func() {
m.Post("/topics", repo.TopicPost)
m.Post("/topics", repo.TopicsPost)
}, context.RepoAssignment(), reqRepoAdmin)

m.Group("/:username/:reponame", func() {
Expand Down

0 comments on commit 42096c6

Please sign in to comment.