1
1
mirror of https://github.com/go-gitea/gitea synced 2025-12-07 13:28:25 +00:00

Merge remote-tracking branch 'upstream/master' into team-grant-all-repos

# Conflicts:
#	models/migrations/migrations.go
#	models/migrations/v90.go
#	models/repo.go
This commit is contained in:
David Svantesson
2019-10-05 14:41:44 +02:00
2331 changed files with 315897 additions and 90391 deletions
+13 -3
View File
@@ -6,10 +6,9 @@
package admin
import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
"code.gitea.io/gitea/routers/api/v1/user"
)
@@ -82,6 +81,15 @@ func GetAllOrgs(ctx *context.APIContext) {
// summary: List all organizations
// produces:
// - application/json
// parameters:
// - name: page
// in: query
// description: page number of results to return (1-based)
// type: integer
// - name: limit
// in: query
// description: page size of results, maximum page size is 50
// type: integer
// responses:
// "200":
// "$ref": "#/responses/OrganizationList"
@@ -90,7 +98,9 @@ func GetAllOrgs(ctx *context.APIContext) {
users, _, err := models.SearchUsers(&models.SearchUserOptions{
Type: models.UserTypeOrganization,
OrderBy: models.SearchOrderByAlphabetically,
PageSize: -1,
Page: ctx.QueryInt("page"),
PageSize: convert.ToCorrectPageSize(ctx.QueryInt("limit")),
Private: true,
})
if err != nil {
ctx.Error(500, "SearchOrganizations", err)
+1 -2
View File
@@ -5,9 +5,8 @@
package admin
import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/repo"
"code.gitea.io/gitea/routers/api/v1/user"
)
+6 -7
View File
@@ -9,10 +9,10 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
"code.gitea.io/gitea/routers/api/v1/user"
"code.gitea.io/gitea/services/mailer"
)
func parseLoginSource(ctx *context.APIContext, u *models.User, sourceID int64, loginName string) {
@@ -88,11 +88,10 @@ func CreateUser(ctx *context.APIContext, form api.CreateUserOption) {
log.Trace("Account created by admin (%s): %s", ctx.User.Name, u.Name)
// Send email notification.
if form.SendNotify && setting.MailService != nil {
models.SendRegisterNotifyMail(ctx.Context.Context, u)
if form.SendNotify {
mailer.SendRegisterNotifyMail(ctx.Locale, u)
}
ctx.JSON(201, u.APIFormat())
ctx.JSON(201, convert.ToUser(u, ctx.IsSigned, ctx.User.IsAdmin))
}
// EditUser api for modifying a user's information
@@ -181,7 +180,7 @@ func EditUser(ctx *context.APIContext, form api.EditUserOption) {
}
log.Trace("Account profile updated by admin (%s): %s", ctx.User.Name, u.Name)
ctx.JSON(200, u.APIFormat())
ctx.JSON(200, convert.ToUser(u, ctx.IsSigned, ctx.User.IsAdmin))
}
// DeleteUser api for deleting a user
@@ -326,7 +325,7 @@ func GetAllUsers(ctx *context.APIContext) {
results := make([]*api.User, len(users))
for i := range users {
results[i] = convert.ToUser(users[i], ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin)
results[i] = convert.ToUser(users[i], ctx.IsSigned, ctx.User.IsAdmin)
}
ctx.JSON(200, &results)
+24 -16
View File
@@ -43,6 +43,7 @@
// type: apiKey
// name: Authorization
// in: header
// description: API tokens must be prepended with "token" followed by a space.
// SudoParam:
// type: apiKey
// name: sudo
@@ -73,9 +74,8 @@ import (
_ "code.gitea.io/gitea/routers/api/v1/swagger" // for swagger generation
"code.gitea.io/gitea/routers/api/v1/user"
"github.com/go-macaron/binding"
"github.com/go-macaron/cors"
macaron "gopkg.in/macaron.v1"
"gitea.com/macaron/binding"
"gitea.com/macaron/macaron"
)
func sudo() macaron.Handler {
@@ -501,12 +501,6 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/swagger", misc.Swagger) //Render V1 by default
}
var handlers []macaron.Handler
if setting.EnableCORS {
handlers = append(handlers, cors.CORS(setting.CORSConfig))
}
handlers = append(handlers, securityHeaders(), context.APIContexter(), sudo())
m.Group("/v1", func() {
// Miscellaneous
if setting.API.EnableSwagger {
@@ -750,10 +744,13 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Combo("/:sha").Get(repo.GetCommitStatuses).
Post(reqToken(), bind(api.CreateStatusOption{}), repo.NewCommitStatus)
}, reqRepoReader(models.UnitTypeCode))
m.Group("/commits/:ref", func() {
// TODO: Add m.Get("") for single commit (https://developer.github.com/v3/repos/commits/#get-a-single-commit)
m.Get("/status", repo.GetCombinedCommitStatusByRef)
m.Get("/statuses", repo.GetCommitStatusesByRef)
m.Group("/commits", func() {
m.Get("", repo.GetAllCommits)
m.Group("/:ref", func() {
// TODO: Add m.Get("") for single commit (https://developer.github.com/v3/repos/commits/#get-a-single-commit)
m.Get("/status", repo.GetCombinedCommitStatusByRef)
m.Get("/statuses", repo.GetCommitStatusesByRef)
})
}, reqRepoReader(models.UnitTypeCode))
m.Group("/git", func() {
m.Group("/commits", func() {
@@ -774,6 +771,14 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Delete("", bind(api.DeleteFileOptions{}), repo.DeleteFile)
}, reqRepoWriter(models.UnitTypeCode), reqToken())
}, reqRepoReader(models.UnitTypeCode))
m.Group("/topics", func() {
m.Combo("").Get(repo.ListTopics).
Put(reqToken(), reqAdmin(), bind(api.RepoTopicOptions{}), repo.UpdateTopics)
m.Group("/:topic", func() {
m.Combo("").Put(reqToken(), repo.AddTopic).
Delete(reqToken(), repo.DeleteTopic)
}, reqAdmin())
}, reqAnyRepoReader())
}, repoAssignment())
})
@@ -797,8 +802,11 @@ func RegisterRoutes(m *macaron.Macaron) {
Put(reqToken(), reqOrgMembership(), org.PublicizeMember).
Delete(reqToken(), reqOrgMembership(), org.ConcealMember)
})
m.Combo("/teams", reqToken(), reqOrgMembership()).Get(org.ListTeams).
Post(reqOrgOwnership(), bind(api.CreateTeamOption{}), org.CreateTeam)
m.Group("/teams", func() {
m.Combo("", reqToken()).Get(org.ListTeams).
Post(reqOrgOwnership(), bind(api.CreateTeamOption{}), org.CreateTeam)
m.Get("/search", org.SearchTeam)
}, reqOrgMembership())
m.Group("/hooks", func() {
m.Combo("").Get(org.ListHooks).
Post(bind(api.CreateHookOption{}), org.CreateHook)
@@ -852,7 +860,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/topics", func() {
m.Get("/search", repo.TopicSearch)
})
}, handlers...)
}, securityHeaders(), context.APIContexter(), sudo())
}
func securityHeaders() macaron.Handler {
+28 -11
View File
@@ -15,7 +15,7 @@ import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"github.com/Unknwon/com"
"github.com/unknwon/com"
)
// ToEmail convert models.EmailAddress to api.Email
@@ -206,14 +206,15 @@ func ToDeployKey(apiLink string, key *models.DeployKey) *api.DeployKey {
// ToOrganization convert models.User to api.Organization
func ToOrganization(org *models.User) *api.Organization {
return &api.Organization{
ID: org.ID,
AvatarURL: org.AvatarLink(),
UserName: org.Name,
FullName: org.FullName,
Description: org.Description,
Website: org.Website,
Location: org.Location,
Visibility: org.Visibility.String(),
ID: org.ID,
AvatarURL: org.AvatarLink(),
UserName: org.Name,
FullName: org.FullName,
Description: org.Description,
Website: org.Website,
Location: org.Location,
Visibility: org.Visibility.String(),
RepoAdminChangeTeamAccess: org.RepoAdminChangeTeamAccess,
}
}
@@ -230,7 +231,7 @@ func ToTeam(team *models.Team) *api.Team {
}
// ToUser convert models.User to api.User
func ToUser(user *models.User, signed, admin bool) *api.User {
func ToUser(user *models.User, signed, authed bool) *api.User {
result := &api.User{
ID: user.ID,
UserName: user.Name,
@@ -240,7 +241,12 @@ func ToUser(user *models.User, signed, admin bool) *api.User {
LastLogin: user.LastLoginUnix.AsTime(),
Created: user.CreatedUnix.AsTime(),
}
if signed && (!user.KeepEmailPrivate || admin) {
// hide primary email if API caller isn't user itself or an admin
if !signed {
result.Email = ""
} else if user.KeepEmailPrivate && !authed {
result.Email = user.GetEmail()
} else {
result.Email = user.Email
}
return result
@@ -287,3 +293,14 @@ func ToCommitMeta(repo *models.Repository, tag *git.Tag) *api.CommitMeta {
URL: util.URLJoin(repo.APIURL(), "git/commits", tag.ID.String()),
}
}
// ToTopicResponse convert from models.Topic to api.TopicResponse
func ToTopicResponse(topic *models.Topic) *api.TopicResponse {
return &api.TopicResponse{
ID: topic.ID,
Name: topic.Name,
RepoCount: topic.RepoCount,
Created: topic.CreatedUnix.AsTime(),
Updated: topic.UpdatedUnix.AsTime(),
}
}
+1 -2
View File
@@ -8,11 +8,10 @@ import (
"net/http"
"strings"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"mvdan.cc/xurls/v2"
+2 -2
View File
@@ -13,9 +13,9 @@ import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"github.com/go-macaron/inject"
"gitea.com/macaron/inject"
"gitea.com/macaron/macaron"
"github.com/stretchr/testify/assert"
macaron "gopkg.in/macaron.v1"
)
const AppURL = "http://localhost:3000/"
+1 -2
View File
@@ -5,10 +5,9 @@
package org
import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
"code.gitea.io/gitea/routers/api/v1/utils"
)
+3 -3
View File
@@ -7,11 +7,11 @@ package org
import (
"fmt"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
"code.gitea.io/gitea/routers/api/v1/user"
)
@@ -46,7 +46,7 @@ func listMembers(ctx *context.APIContext, publicOnly bool) {
apiMembers := make([]*api.User, len(members))
for i, member := range members {
apiMembers[i] = member.APIFormat()
apiMembers[i] = convert.ToUser(member, ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin)
}
ctx.JSON(200, apiMembers)
}
+10 -10
View File
@@ -6,10 +6,9 @@
package org
import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
"code.gitea.io/gitea/routers/api/v1/user"
)
@@ -96,14 +95,15 @@ func Create(ctx *context.APIContext, form api.CreateOrgOption) {
}
org := &models.User{
Name: form.UserName,
FullName: form.FullName,
Description: form.Description,
Website: form.Website,
Location: form.Location,
IsActive: true,
Type: models.UserTypeOrganization,
Visibility: visibility,
Name: form.UserName,
FullName: form.FullName,
Description: form.Description,
Website: form.Website,
Location: form.Location,
IsActive: true,
Type: models.UserTypeOrganization,
Visibility: visibility,
RepoAdminChangeTeamAccess: form.RepoAdminChangeTeamAccess,
}
if err := models.CreateOrganization(org, ctx.User); err != nil {
if models.IsErrUserAlreadyExist(err) ||
+94 -3
View File
@@ -6,10 +6,12 @@
package org
import (
api "code.gitea.io/gitea/modules/structs"
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
"code.gitea.io/gitea/routers/api/v1/user"
)
@@ -259,7 +261,7 @@ func GetTeamMembers(ctx *context.APIContext) {
}
members := make([]*api.User, len(team.Members))
for i, member := range team.Members {
members[i] = member.APIFormat()
members[i] = convert.ToUser(member, ctx.IsSigned, ctx.User.IsAdmin)
}
ctx.JSON(200, members)
}
@@ -290,7 +292,16 @@ func GetTeamMember(ctx *context.APIContext) {
if ctx.Written() {
return
}
ctx.JSON(200, u.APIFormat())
teamID := ctx.ParamsInt64("teamid")
isTeamMember, err := models.IsUserInTeams(u.ID, []int64{teamID})
if err != nil {
ctx.Error(500, "IsUserInTeams", err)
return
} else if !isTeamMember {
ctx.NotFound()
return
}
ctx.JSON(200, convert.ToUser(u, ctx.IsSigned, ctx.User.IsAdmin))
}
// AddTeamMember api for add a member to a team
@@ -498,3 +509,83 @@ func RemoveTeamRepository(ctx *context.APIContext) {
}
ctx.Status(204)
}
// SearchTeam api for searching teams
func SearchTeam(ctx *context.APIContext) {
// swagger:operation GET /orgs/{org}/teams/search organization teamSearch
// ---
// summary: Search for teams within an organization
// produces:
// - application/json
// parameters:
// - name: org
// in: path
// description: name of the organization
// type: string
// required: true
// - name: q
// in: query
// description: keywords to search
// type: string
// - name: include_desc
// in: query
// description: include search within team description (defaults to true)
// type: boolean
// - name: limit
// in: query
// description: limit size of results
// type: integer
// - name: page
// in: query
// description: page number of results to return (1-based)
// type: integer
// responses:
// "200":
// description: "SearchResults of a successful search"
// schema:
// type: object
// properties:
// ok:
// type: boolean
// data:
// type: array
// items:
// "$ref": "#/definitions/Team"
opts := &models.SearchTeamOptions{
UserID: ctx.User.ID,
Keyword: strings.TrimSpace(ctx.Query("q")),
OrgID: ctx.Org.Organization.ID,
IncludeDesc: (ctx.Query("include_desc") == "" || ctx.QueryBool("include_desc")),
PageSize: ctx.QueryInt("limit"),
Page: ctx.QueryInt("page"),
}
teams, _, err := models.SearchTeam(opts)
if err != nil {
log.Error("SearchTeam failed: %v", err)
ctx.JSON(500, map[string]interface{}{
"ok": false,
"error": "SearchTeam internal failure",
})
return
}
apiTeams := make([]*api.Team, len(teams))
for i := range teams {
if err := teams[i].GetUnits(); err != nil {
log.Error("Team GetUnits failed: %v", err)
ctx.JSON(500, map[string]interface{}{
"ok": false,
"error": "SearchTeam failed to get units",
})
return
}
apiTeams[i] = convert.ToTeam(teams[i])
}
ctx.JSON(200, map[string]interface{}{
"ok": true,
"data": apiTeams,
})
}
+1 -2
View File
@@ -8,9 +8,8 @@ package repo
import (
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/routers/api/v1/convert"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
)
// GetBranch get a branch of a repository
+2 -2
View File
@@ -10,8 +10,8 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
)
// ListCollaborators list a repository's collaborators
@@ -42,7 +42,7 @@ func ListCollaborators(ctx *context.APIContext) {
}
users := make([]*api.User, len(collaborators))
for i, collaborator := range collaborators {
users[i] = collaborator.APIFormat()
users[i] = convert.ToUser(collaborator.User, ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin)
}
ctx.JSON(200, users)
}
+185 -22
View File
@@ -6,6 +6,8 @@
package repo
import (
"math"
"strconv"
"time"
"code.gitea.io/gitea/models"
@@ -55,25 +57,186 @@ func GetSingleCommit(ctx *context.APIContext) {
return
}
// Retrieve author and committer information
var apiAuthor, apiCommitter *api.User
author, err := models.GetUserByEmail(commit.Author.Email)
if err != nil && !models.IsErrUserNotExist(err) {
ctx.ServerError("Get user by author email", err)
json, err := toCommit(ctx, ctx.Repo.Repository, commit, nil)
if err != nil {
ctx.ServerError("toCommit", err)
return
} else if err == nil {
apiAuthor = author.APIFormat()
}
// Save one query if the author is also the committer
if commit.Committer.Email == commit.Author.Email {
apiCommitter = apiAuthor
ctx.JSON(200, json)
}
// GetAllCommits get all commits via
func GetAllCommits(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/commits repository repoGetAllCommits
// ---
// summary: Get a list of all commits from a repository
// produces:
// - application/json
// parameters:
// - name: owner
// in: path
// description: owner of the repo
// type: string
// required: true
// - name: repo
// in: path
// description: name of the repo
// type: string
// required: true
// - name: sha
// in: query
// description: SHA or branch to start listing commits from (usually 'master')
// type: string
// - name: page
// in: query
// description: page number of requested commits
// type: integer
// responses:
// "200":
// "$ref": "#/responses/CommitList"
// "404":
// "$ref": "#/responses/notFound"
// "409":
// "$ref": "#/responses/EmptyRepository"
if ctx.Repo.Repository.IsEmpty {
ctx.JSON(409, api.APIError{
Message: "Git Repository is empty.",
URL: setting.API.SwaggerURL,
})
return
}
gitRepo, err := git.OpenRepository(ctx.Repo.Repository.RepoPath())
if err != nil {
ctx.ServerError("OpenRepository", err)
return
}
page := ctx.QueryInt("page")
if page <= 0 {
page = 1
}
sha := ctx.Query("sha")
var baseCommit *git.Commit
if len(sha) == 0 {
// no sha supplied - use default branch
head, err := gitRepo.GetHEADBranch()
if err != nil {
ctx.ServerError("GetHEADBranch", err)
return
}
baseCommit, err = gitRepo.GetBranchCommit(head.Name)
if err != nil {
ctx.ServerError("GetCommit", err)
return
}
} else {
// get commit specified by sha
baseCommit, err = gitRepo.GetCommit(sha)
if err != nil {
ctx.ServerError("GetCommit", err)
return
}
}
// Total commit count
commitsCountTotal, err := baseCommit.CommitsCount()
if err != nil {
ctx.ServerError("GetCommitsCount", err)
return
}
pageCount := int(math.Ceil(float64(commitsCountTotal) / float64(git.CommitsRangeSize)))
// Query commits
commits, err := baseCommit.CommitsByRange(page)
if err != nil {
ctx.ServerError("CommitsByRange", err)
return
}
userCache := make(map[string]*models.User)
apiCommits := make([]*api.Commit, commits.Len())
i := 0
for commitPointer := commits.Front(); commitPointer != nil; commitPointer = commitPointer.Next() {
commit := commitPointer.Value.(*git.Commit)
// Create json struct
apiCommits[i], err = toCommit(ctx, ctx.Repo.Repository, commit, userCache)
if err != nil {
ctx.ServerError("toCommit", err)
return
}
i++
}
ctx.SetLinkHeader(int(commitsCountTotal), git.CommitsRangeSize)
ctx.Header().Set("X-Page", strconv.Itoa(page))
ctx.Header().Set("X-PerPage", strconv.Itoa(git.CommitsRangeSize))
ctx.Header().Set("X-Total", strconv.FormatInt(commitsCountTotal, 10))
ctx.Header().Set("X-PageCount", strconv.Itoa(pageCount))
ctx.Header().Set("X-HasMore", strconv.FormatBool(page < pageCount))
ctx.JSON(200, &apiCommits)
}
func toCommit(ctx *context.APIContext, repo *models.Repository, commit *git.Commit, userCache map[string]*models.User) (*api.Commit, error) {
var apiAuthor, apiCommitter *api.User
// Retrieve author and committer information
var cacheAuthor *models.User
var ok bool
if userCache == nil {
cacheAuthor = ((*models.User)(nil))
ok = false
} else {
cacheAuthor, ok = userCache[commit.Author.Email]
}
if ok {
apiAuthor = cacheAuthor.APIFormat()
} else {
author, err := models.GetUserByEmail(commit.Author.Email)
if err != nil && !models.IsErrUserNotExist(err) {
return nil, err
} else if err == nil {
apiAuthor = author.APIFormat()
if userCache != nil {
userCache[commit.Author.Email] = author
}
}
}
var cacheCommitter *models.User
if userCache == nil {
cacheCommitter = ((*models.User)(nil))
ok = false
} else {
cacheCommitter, ok = userCache[commit.Committer.Email]
}
if ok {
apiCommitter = cacheCommitter.APIFormat()
} else {
committer, err := models.GetUserByEmail(commit.Committer.Email)
if err != nil && !models.IsErrUserNotExist(err) {
ctx.ServerError("Get user by committer email", err)
return
return nil, err
} else if err == nil {
apiCommitter = committer.APIFormat()
if userCache != nil {
userCache[commit.Committer.Email] = committer
}
}
}
@@ -82,23 +245,23 @@ func GetSingleCommit(ctx *context.APIContext) {
for i := 0; i < commit.ParentCount(); i++ {
sha, _ := commit.ParentID(i)
apiParents[i] = &api.CommitMeta{
URL: ctx.Repo.Repository.APIURL() + "/git/commits/" + sha.String(),
URL: repo.APIURL() + "/git/commits/" + sha.String(),
SHA: sha.String(),
}
}
ctx.JSON(200, &api.Commit{
return &api.Commit{
CommitMeta: &api.CommitMeta{
URL: setting.AppURL + ctx.Link[1:],
URL: repo.APIURL() + "/git/commits/" + commit.ID.String(),
SHA: commit.ID.String(),
},
HTMLURL: ctx.Repo.Repository.HTMLURL() + "/commits/" + commit.ID.String(),
HTMLURL: repo.HTMLURL() + "/commit/" + commit.ID.String(),
RepoCommit: &api.RepoCommit{
URL: setting.AppURL + ctx.Link[1:],
URL: repo.APIURL() + "/git/commits/" + commit.ID.String(),
Author: &api.CommitUser{
Identity: api.Identity{
Name: commit.Author.Name,
Email: commit.Author.Email,
Name: commit.Committer.Name,
Email: commit.Committer.Email,
},
Date: commit.Author.When.Format(time.RFC3339),
},
@@ -109,14 +272,14 @@ func GetSingleCommit(ctx *context.APIContext) {
},
Date: commit.Committer.When.Format(time.RFC3339),
},
Message: commit.Message(),
Message: commit.Summary(),
Tree: &api.CommitMeta{
URL: ctx.Repo.Repository.APIURL() + "/trees/" + commit.ID.String(),
URL: repo.APIURL() + "/git/trees/" + commit.ID.String(),
SHA: commit.ID.String(),
},
},
Author: apiAuthor,
Committer: apiCommitter,
Parents: apiParents,
})
}, nil
}
-1
View File
@@ -7,7 +7,6 @@ package repo
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
)
+8 -5
View File
@@ -71,19 +71,22 @@ func GetGitRefs(ctx *context.APIContext) {
getGitRefsInternal(ctx, ctx.Params("*"))
}
func getGitRefsInternal(ctx *context.APIContext, filter string) {
func getGitRefs(ctx *context.APIContext, filter string) ([]*git.Reference, string, error) {
gitRepo, err := git.OpenRepository(ctx.Repo.Repository.RepoPath())
if err != nil {
ctx.Error(500, "OpenRepository", err)
return
return nil, "OpenRepository", err
}
if len(filter) > 0 {
filter = "refs/" + filter
}
refs, err := gitRepo.GetRefsFiltered(filter)
return refs, "GetRefsFiltered", err
}
func getGitRefsInternal(ctx *context.APIContext, filter string) {
refs, lastMethodName, err := getGitRefs(ctx, filter)
if err != nil {
ctx.Error(500, "GetRefsFiltered", err)
ctx.Error(500, lastMethodName, err)
return
}
+2 -2
View File
@@ -130,8 +130,8 @@ func TestHook(ctx *context.APIContext) {
convert.ToCommit(ctx.Repo.Repository, ctx.Repo.Commit),
},
Repo: ctx.Repo.Repository.APIFormat(models.AccessModeNone),
Pusher: ctx.User.APIFormat(),
Sender: ctx.User.APIFormat(),
Pusher: convert.ToUser(ctx.User, ctx.IsSigned, false),
Sender: convert.ToUser(ctx.User, ctx.IsSigned, false),
}); err != nil {
ctx.Error(500, "PrepareWebhook: ", err)
return
+12 -10
View File
@@ -16,9 +16,11 @@ import (
issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
"code.gitea.io/gitea/modules/notification"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
issue_service "code.gitea.io/gitea/services/issue"
milestone_service "code.gitea.io/gitea/services/milestone"
)
// ListIssues list the issues of a repository
@@ -183,9 +185,9 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) {
// "201":
// "$ref": "#/responses/Issue"
var deadlineUnix util.TimeStamp
var deadlineUnix timeutil.TimeStamp
if form.Deadline != nil && ctx.Repo.CanWrite(models.UnitTypeIssues) {
deadlineUnix = util.TimeStamp(form.Deadline.Unix())
deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
}
issue := &models.Issue{
@@ -216,7 +218,7 @@ func CreateIssue(ctx *context.APIContext, form api.CreateIssueOption) {
form.Labels = make([]int64, 0)
}
if err := models.NewIssue(ctx.Repo.Repository, issue, form.Labels, assigneeIDs, nil); err != nil {
if err := issue_service.NewIssue(ctx.Repo.Repository, issue, form.Labels, assigneeIDs, nil); err != nil {
if models.IsErrUserDoesNotHaveAccessToRepo(err) {
ctx.Error(400, "UserDoesNotHaveAccessToRepo", err)
return
@@ -310,9 +312,9 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
}
// Update the deadline
var deadlineUnix util.TimeStamp
var deadlineUnix timeutil.TimeStamp
if form.Deadline != nil && !form.Deadline.IsZero() && ctx.Repo.CanWrite(models.UnitTypeIssues) {
deadlineUnix = util.TimeStamp(form.Deadline.Unix())
deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
}
if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil {
@@ -345,7 +347,7 @@ func EditIssue(ctx *context.APIContext, form api.EditIssueOption) {
issue.MilestoneID != *form.Milestone {
oldMilestoneID := issue.MilestoneID
issue.MilestoneID = *form.Milestone
if err = models.ChangeMilestoneAssign(issue, ctx.User, oldMilestoneID); err != nil {
if err = milestone_service.ChangeMilestoneAssign(issue, ctx.User, oldMilestoneID); err != nil {
ctx.Error(500, "ChangeMilestoneAssign", err)
return
}
@@ -430,12 +432,12 @@ func UpdateIssueDeadline(ctx *context.APIContext, form api.EditDeadlineOption) {
return
}
var deadlineUnix util.TimeStamp
var deadlineUnix timeutil.TimeStamp
var deadline time.Time
if form.Deadline != nil && !form.Deadline.IsZero() {
deadline = time.Date(form.Deadline.Year(), form.Deadline.Month(), form.Deadline.Day(),
23, 59, 59, 0, form.Deadline.Location())
deadlineUnix = util.TimeStamp(deadline.Unix())
deadlineUnix = timeutil.TimeStamp(deadline.Unix())
}
if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil {
+4 -4
View File
@@ -11,8 +11,8 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/notification"
api "code.gitea.io/gitea/modules/structs"
comment_service "code.gitea.io/gitea/services/comments"
)
// ListIssueComments list all the comments of an issue
@@ -190,7 +190,7 @@ func CreateIssueComment(ctx *context.APIContext, form api.CreateIssueCommentOpti
return
}
comment, err := models.CreateIssueComment(ctx.User, ctx.Repo.Repository, issue, form.Body, nil)
comment, err := comment_service.CreateIssueComment(ctx.User, ctx.Repo.Repository, issue, form.Body, nil)
if err != nil {
ctx.Error(500, "CreateIssueComment", err)
return
@@ -300,7 +300,7 @@ func editIssueComment(ctx *context.APIContext, form api.EditIssueCommentOption)
oldContent := comment.Content
comment.Content = form.Body
if err := models.UpdateComment(ctx.User, comment, oldContent); err != nil {
if err := comment_service.UpdateComment(comment, ctx.User, oldContent); err != nil {
ctx.Error(500, "UpdateComment", err)
return
}
@@ -391,7 +391,7 @@ func deleteIssueComment(ctx *context.APIContext) {
return
}
if err = models.DeleteComment(ctx.User, comment); err != nil {
if err = comment_service.DeleteComment(comment, ctx.User); err != nil {
ctx.Error(500, "DeleteCommentByID", err)
return
}
-1
View File
@@ -8,7 +8,6 @@ package repo
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
)
@@ -7,7 +7,6 @@ package repo
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
)
+1 -2
View File
@@ -10,9 +10,8 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers/api/v1/convert"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
)
// appendPrivateInformation appends the owner and key type information to api.PublicKey
-1
View File
@@ -10,7 +10,6 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
)
+3 -4
View File
@@ -9,9 +9,8 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/util"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/timeutil"
)
// ListMilestones list milestones for a repository
@@ -127,7 +126,7 @@ func CreateMilestone(ctx *context.APIContext, form api.CreateMilestoneOption) {
RepoID: ctx.Repo.Repository.ID,
Name: form.Title,
Content: form.Description,
DeadlineUnix: util.TimeStamp(form.Deadline.Unix()),
DeadlineUnix: timeutil.TimeStamp(form.Deadline.Unix()),
}
if err := models.NewMilestone(milestone); err != nil {
@@ -187,7 +186,7 @@ func EditMilestone(ctx *context.APIContext, form api.EditMilestoneOption) {
milestone.Content = *form.Description
}
if form.Deadline != nil && !form.Deadline.IsZero() {
milestone.DeadlineUnix = util.TimeStamp(form.Deadline.Unix())
milestone.DeadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
}
if err := models.UpdateMilestone(milestone); err != nil {
+21 -16
View File
@@ -15,9 +15,10 @@ import (
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/notification"
"code.gitea.io/gitea/modules/pull"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/timeutil"
milestone_service "code.gitea.io/gitea/services/milestone"
pull_service "code.gitea.io/gitea/services/pull"
)
// ListPullRequests returns a list of all PRs
@@ -247,20 +248,13 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption
return
}
var deadlineUnix util.TimeStamp
var deadlineUnix timeutil.TimeStamp
if form.Deadline != nil {
deadlineUnix = util.TimeStamp(form.Deadline.Unix())
}
maxIndex, err := models.GetMaxIndexOfIssue(repo.ID)
if err != nil {
ctx.ServerError("GetPatch", err)
return
deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
}
prIssue := &models.Issue{
RepoID: repo.ID,
Index: maxIndex + 1,
Title: form.Title,
PosterID: ctx.User.ID,
Poster: ctx.User,
@@ -293,7 +287,7 @@ func CreatePullRequest(ctx *context.APIContext, form api.CreatePullRequestOption
return
}
if err := models.NewPullRequest(repo, prIssue, labelIDs, []string{}, pr, patch, assigneeIDs); err != nil {
if err := pull_service.NewPullRequest(repo, prIssue, labelIDs, []string{}, pr, patch, assigneeIDs); err != nil {
if models.IsErrUserDoesNotHaveAccessToRepo(err) {
ctx.Error(400, "UserDoesNotHaveAccessToRepo", err)
return
@@ -375,9 +369,9 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) {
}
// Update Deadline
var deadlineUnix util.TimeStamp
var deadlineUnix timeutil.TimeStamp
if form.Deadline != nil && !form.Deadline.IsZero() {
deadlineUnix = util.TimeStamp(form.Deadline.Unix())
deadlineUnix = timeutil.TimeStamp(form.Deadline.Unix())
}
if err := models.UpdateIssueDeadline(issue, deadlineUnix, ctx.User); err != nil {
@@ -409,7 +403,7 @@ func EditPullRequest(ctx *context.APIContext, form api.EditPullRequestOption) {
issue.MilestoneID != form.Milestone {
oldMilestoneID := issue.MilestoneID
issue.MilestoneID = form.Milestone
if err = models.ChangeMilestoneAssign(issue, ctx.User, oldMilestoneID); err != nil {
if err = milestone_service.ChangeMilestoneAssign(issue, ctx.User, oldMilestoneID); err != nil {
ctx.Error(500, "ChangeMilestoneAssign", err)
return
}
@@ -577,6 +571,17 @@ func MergePullRequest(ctx *context.APIContext, form auth.MergePullRequestForm) {
return
}
isPass, err := pull_service.IsPullCommitStatusPass(pr)
if err != nil {
ctx.Error(500, "IsPullCommitStatusPass", err)
return
}
if !isPass && !ctx.IsUserRepoAdmin() {
ctx.Status(405)
return
}
if len(form.Do) == 0 {
form.Do = string(models.MergeStyleMerge)
}
@@ -596,7 +601,7 @@ func MergePullRequest(ctx *context.APIContext, form auth.MergePullRequestForm) {
message += "\n\n" + form.MergeMessageField
}
if err := pull.Merge(pr, ctx.User, ctx.Repo.GitRepo, models.MergeStyle(form.Do), message); err != nil {
if err := pull_service.Merge(pr, ctx.User, ctx.Repo.GitRepo, models.MergeStyle(form.Do), message); err != nil {
if models.IsErrInvalidMergeStyle(err) {
ctx.Status(405)
return
+5 -5
View File
@@ -8,8 +8,8 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
releaseservice "code.gitea.io/gitea/services/release"
)
// GetRelease get a single release of a repository
@@ -169,7 +169,7 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) {
IsTag: false,
Repo: ctx.Repo.Repository,
}
if err := models.CreateRelease(ctx.Repo.GitRepo, rel, nil); err != nil {
if err := releaseservice.CreateRelease(ctx.Repo.GitRepo, rel, nil); err != nil {
if models.IsErrReleaseAlreadyExist(err) {
ctx.Status(409)
} else {
@@ -192,7 +192,7 @@ func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) {
rel.Repo = ctx.Repo.Repository
rel.Publisher = ctx.User
if err = models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
if err = releaseservice.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
ctx.ServerError("UpdateRelease", err)
return
}
@@ -263,7 +263,7 @@ func EditRelease(ctx *context.APIContext, form api.EditReleaseOption) {
if form.IsPrerelease != nil {
rel.IsPrerelease = *form.IsPrerelease
}
if err := models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
if err := releaseservice.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
ctx.Error(500, "UpdateRelease", err)
return
}
@@ -316,7 +316,7 @@ func DeleteRelease(ctx *context.APIContext) {
ctx.NotFound()
return
}
if err := models.DeleteReleaseByID(id, ctx.User, false); err != nil {
if err := releaseservice.DeleteReleaseByID(id, ctx.User, false); err != nil {
ctx.Error(500, "DeleteReleaseByID", err)
return
}
+7 -4
View File
@@ -9,10 +9,10 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/upload"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/upload"
)
// GetReleaseAttachment gets a single attachment of the release
@@ -56,6 +56,7 @@ func GetReleaseAttachment(ctx *context.APIContext) {
return
}
if attach.ReleaseID != releaseID {
log.Info("User requested attachment is not in release, release_id %v, attachment_id: %v", releaseID, attachID)
ctx.NotFound()
return
}
@@ -243,13 +244,14 @@ func EditReleaseAttachment(ctx *context.APIContext, form api.EditAttachmentOptio
// Check if release exists an load release
releaseID := ctx.ParamsInt64(":id")
attachID := ctx.ParamsInt64(":attachment")
attachID := ctx.ParamsInt64(":asset")
attach, err := models.GetAttachmentByID(attachID)
if err != nil {
ctx.Error(500, "GetAttachmentByID", err)
return
}
if attach.ReleaseID != releaseID {
log.Info("User requested attachment is not in release, release_id %v, attachment_id: %v", releaseID, attachID)
ctx.NotFound()
return
}
@@ -300,13 +302,14 @@ func DeleteReleaseAttachment(ctx *context.APIContext) {
// Check if release exists an load release
releaseID := ctx.ParamsInt64(":id")
attachID := ctx.ParamsInt64(":attachment")
attachID := ctx.ParamsInt64(":asset")
attach, err := models.GetAttachmentByID(attachID)
if err != nil {
ctx.Error(500, "GetAttachmentByID", err)
return
}
if attach.ReleaseID != releaseID {
log.Info("User requested attachment is not in release, release_id %v, attachment_id: %v", releaseID, attachID)
ctx.NotFound()
return
}
+143 -112
View File
@@ -15,11 +15,13 @@ import (
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/migrations"
"code.gitea.io/gitea/modules/notification"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/routers/api/v1/convert"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/validation"
"code.gitea.io/gitea/routers/api/v1/convert"
mirror_service "code.gitea.io/gitea/services/mirror"
)
var searchOrderByMap = map[string]map[string]models.SearchOrderBy{
@@ -51,6 +53,14 @@ func Search(ctx *context.APIContext) {
// in: query
// description: keyword
// type: string
// - name: topic
// in: query
// description: Limit search to repositories with keyword as topic
// type: boolean
// - name: includeDesc
// in: query
// description: include search of keyword within repository description
// type: boolean
// - name: uid
// in: query
// description: search only for repos that the user with the given id owns or contributes to
@@ -99,16 +109,17 @@ func Search(ctx *context.APIContext) {
// "422":
// "$ref": "#/responses/validationError"
opts := &models.SearchRepoOptions{
Keyword: strings.Trim(ctx.Query("q"), " "),
OwnerID: ctx.QueryInt64("uid"),
Page: ctx.QueryInt("page"),
PageSize: convert.ToCorrectPageSize(ctx.QueryInt("limit")),
TopicOnly: ctx.QueryBool("topic"),
Collaborate: util.OptionalBoolNone,
Private: ctx.IsSigned && (ctx.Query("private") == "" || ctx.QueryBool("private")),
UserIsAdmin: ctx.IsUserSiteAdmin(),
UserID: ctx.Data["SignedUserID"].(int64),
StarredByID: ctx.QueryInt64("starredBy"),
Keyword: strings.Trim(ctx.Query("q"), " "),
OwnerID: ctx.QueryInt64("uid"),
Page: ctx.QueryInt("page"),
PageSize: convert.ToCorrectPageSize(ctx.QueryInt("limit")),
TopicOnly: ctx.QueryBool("topic"),
Collaborate: util.OptionalBoolNone,
Private: ctx.IsSigned && (ctx.Query("private") == "" || ctx.QueryBool("private")),
UserIsAdmin: ctx.IsUserSiteAdmin(),
UserID: ctx.Data["SignedUserID"].(int64),
StarredByID: ctx.QueryInt64("starredBy"),
IncludeDescription: ctx.QueryBool("includeDesc"),
}
if ctx.QueryBool("exclusive") {
@@ -153,7 +164,7 @@ func Search(ctx *context.APIContext) {
}
var err error
repos, count, err := models.SearchRepositoryByName(opts)
repos, count, err := models.SearchRepository(opts)
if err != nil {
ctx.JSON(500, api.SearchError{
OK: false,
@@ -197,6 +208,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *models.User, opt api.CreateR
repo, err := models.CreateRepository(ctx.User, owner, models.CreateRepoOptions{
Name: opt.Name,
Description: opt.Description,
IssueLabels: opt.IssueLabels,
Gitignores: opt.Gitignores,
License: opt.License,
Readme: opt.Readme,
@@ -220,6 +232,8 @@ func CreateUserRepo(ctx *context.APIContext, owner *models.User, opt api.CreateR
return
}
notification.NotifyCreateRepository(ctx.User, owner, repo)
ctx.JSON(201, repo.APIFormat(models.AccessModeOwner))
}
@@ -410,6 +424,8 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
repo, err := migrations.MigrateRepository(ctx.User, ctxUser.Name, opts)
if err == nil {
notification.NotifyCreateRepository(ctx.User, ctxUser, repo)
log.Trace("Repository migrated: %s/%s", ctxUser.Name, form.RepoName)
ctx.JSON(201, repo.APIFormat(models.AccessModeAdmin))
return
@@ -646,15 +662,48 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
})
}
if opts.HasIssues != nil {
if *opts.HasIssues {
// We don't currently allow setting individual issue settings through the API,
// only can enable/disable issues, so when enabling issues,
// we either get the existing config which means it was already enabled,
// or create a new config since it doesn't exist.
unit, err := repo.GetUnit(models.UnitTypeIssues)
if opts.HasIssues == nil {
// If HasIssues setting not touched, rewrite existing repo unit
if unit, err := repo.GetUnit(models.UnitTypeIssues); err == nil {
units = append(units, *unit)
} else if unit, err := repo.GetUnit(models.UnitTypeExternalTracker); err == nil {
units = append(units, *unit)
}
} else if *opts.HasIssues {
if opts.ExternalTracker != nil {
// Check that values are valid
if !validation.IsValidExternalURL(opts.ExternalTracker.ExternalTrackerURL) {
err := fmt.Errorf("External tracker URL not valid")
ctx.Error(http.StatusUnprocessableEntity, "Invalid external tracker URL", err)
return err
}
if len(opts.ExternalTracker.ExternalTrackerFormat) != 0 && !validation.IsValidExternalTrackerURLFormat(opts.ExternalTracker.ExternalTrackerFormat) {
err := fmt.Errorf("External tracker URL format not valid")
ctx.Error(http.StatusUnprocessableEntity, "Invalid external tracker URL format", err)
return err
}
units = append(units, models.RepoUnit{
RepoID: repo.ID,
Type: models.UnitTypeExternalTracker,
Config: &models.ExternalTrackerConfig{
ExternalTrackerURL: opts.ExternalTracker.ExternalTrackerURL,
ExternalTrackerFormat: opts.ExternalTracker.ExternalTrackerFormat,
ExternalTrackerStyle: opts.ExternalTracker.ExternalTrackerStyle,
},
})
} else {
// Default to built-in tracker
var config *models.IssuesConfig
if err != nil {
if opts.InternalTracker != nil {
config = &models.IssuesConfig{
EnableTimetracker: opts.InternalTracker.EnableTimeTracker,
AllowOnlyContributorsToTrackTime: opts.InternalTracker.AllowOnlyContributorsToTrackTime,
EnableDependencies: opts.InternalTracker.EnableIssueDependencies,
}
} else if unit, err := repo.GetUnit(models.UnitTypeIssues); err != nil {
// Unit type doesn't exist so we make a new config file with default values
config = &models.IssuesConfig{
EnableTimetracker: true,
@@ -664,6 +713,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
} else {
config = unit.IssuesConfig()
}
units = append(units, models.RepoUnit{
RepoID: repo.ID,
Type: models.UnitTypeIssues,
@@ -672,12 +722,31 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
}
}
if opts.HasWiki != nil {
if *opts.HasWiki {
// We don't currently allow setting individual wiki settings through the API,
// only can enable/disable the wiki, so when enabling the wiki,
// we either get the existing config which means it was already enabled,
// or create a new config since it doesn't exist.
if opts.HasWiki == nil {
// If HasWiki setting not touched, rewrite existing repo unit
if unit, err := repo.GetUnit(models.UnitTypeWiki); err == nil {
units = append(units, *unit)
} else if unit, err := repo.GetUnit(models.UnitTypeExternalWiki); err == nil {
units = append(units, *unit)
}
} else if *opts.HasWiki {
if opts.ExternalWiki != nil {
// Check that values are valid
if !validation.IsValidExternalURL(opts.ExternalWiki.ExternalWikiURL) {
err := fmt.Errorf("External wiki URL not valid")
ctx.Error(http.StatusUnprocessableEntity, "", "Invalid external wiki URL")
return err
}
units = append(units, models.RepoUnit{
RepoID: repo.ID,
Type: models.UnitTypeExternalWiki,
Config: &models.ExternalWikiConfig{
ExternalWikiURL: opts.ExternalWiki.ExternalWikiURL,
},
})
} else {
config := &models.UnitConfig{}
units = append(units, models.RepoUnit{
RepoID: repo.ID,
@@ -687,48 +756,51 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
}
}
if opts.HasPullRequests != nil {
if *opts.HasPullRequests {
// We do allow setting individual PR settings through the API, so
// we get the config settings and then set them
// if those settings were provided in the opts.
unit, err := repo.GetUnit(models.UnitTypePullRequests)
var config *models.PullRequestsConfig
if err != nil {
// Unit type doesn't exist so we make a new config file with default values
config = &models.PullRequestsConfig{
IgnoreWhitespaceConflicts: false,
AllowMerge: true,
AllowRebase: true,
AllowRebaseMerge: true,
AllowSquash: true,
}
} else {
config = unit.PullRequestsConfig()
}
if opts.IgnoreWhitespaceConflicts != nil {
config.IgnoreWhitespaceConflicts = *opts.IgnoreWhitespaceConflicts
}
if opts.AllowMerge != nil {
config.AllowMerge = *opts.AllowMerge
}
if opts.AllowRebase != nil {
config.AllowRebase = *opts.AllowRebase
}
if opts.AllowRebaseMerge != nil {
config.AllowRebaseMerge = *opts.AllowRebaseMerge
}
if opts.AllowSquash != nil {
config.AllowSquash = *opts.AllowSquash
}
units = append(units, models.RepoUnit{
RepoID: repo.ID,
Type: models.UnitTypePullRequests,
Config: config,
})
if opts.HasPullRequests == nil {
// If HasPullRequest setting not touched, rewrite existing repo unit
if unit, err := repo.GetUnit(models.UnitTypePullRequests); err == nil {
units = append(units, *unit)
}
} else if *opts.HasPullRequests {
// We do allow setting individual PR settings through the API, so
// we get the config settings and then set them
// if those settings were provided in the opts.
unit, err := repo.GetUnit(models.UnitTypePullRequests)
var config *models.PullRequestsConfig
if err != nil {
// Unit type doesn't exist so we make a new config file with default values
config = &models.PullRequestsConfig{
IgnoreWhitespaceConflicts: false,
AllowMerge: true,
AllowRebase: true,
AllowRebaseMerge: true,
AllowSquash: true,
}
} else {
config = unit.PullRequestsConfig()
}
if opts.IgnoreWhitespaceConflicts != nil {
config.IgnoreWhitespaceConflicts = *opts.IgnoreWhitespaceConflicts
}
if opts.AllowMerge != nil {
config.AllowMerge = *opts.AllowMerge
}
if opts.AllowRebase != nil {
config.AllowRebase = *opts.AllowRebase
}
if opts.AllowRebaseMerge != nil {
config.AllowRebaseMerge = *opts.AllowRebaseMerge
}
if opts.AllowSquash != nil {
config.AllowSquash = *opts.AllowSquash
}
units = append(units, models.RepoUnit{
RepoID: repo.ID,
Type: models.UnitTypePullRequests,
Config: config,
})
}
if err := models.UpdateRepositoryUnits(repo, units); err != nil {
@@ -842,48 +914,7 @@ func MirrorSync(ctx *context.APIContext) {
ctx.Error(403, "MirrorSync", "Must have write access")
}
go models.MirrorQueue.Add(repo.ID)
mirror_service.StartToMirror(repo.ID)
ctx.Status(200)
}
// TopicSearch search for creating topic
func TopicSearch(ctx *context.Context) {
// swagger:operation GET /topics/search repository topicSearch
// ---
// summary: search topics via keyword
// produces:
// - application/json
// parameters:
// - name: q
// in: query
// description: keywords to search
// required: true
// type: string
// responses:
// "200":
// "$ref": "#/responses/Repository"
if ctx.User == nil {
ctx.JSON(403, map[string]interface{}{
"message": "Only owners could change the topics.",
})
return
}
kw := ctx.Query("q")
topics, err := models.FindTopics(&models.FindTopicOptions{
Keyword: kw,
Limit: 10,
})
if err != nil {
log.Error("SearchTopics failed: %v", err)
ctx.JSON(500, map[string]interface{}{
"message": "Search topics failed.",
})
return
}
ctx.JSON(200, map[string]interface{}{
"topics": topics,
})
}
+2 -2
View File
@@ -6,8 +6,8 @@ package repo
import (
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
)
// ListStargazers list a repository's stargazers
@@ -38,7 +38,7 @@ func ListStargazers(ctx *context.APIContext) {
}
users := make([]*api.User, len(stargazers))
for i, stargazer := range stargazers {
users[i] = stargazer.APIFormat()
users[i] = convert.ToUser(stargazer, ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin)
}
ctx.JSON(200, users)
}
+79 -11
View File
@@ -10,7 +10,6 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/repofiles"
api "code.gitea.io/gitea/modules/structs"
)
@@ -46,10 +45,7 @@ func NewCommitStatus(ctx *context.APIContext, form api.CreateStatusOption) {
// "$ref": "#/responses/StatusList"
sha := ctx.Params("sha")
if len(sha) == 0 {
sha = ctx.Params("ref")
}
if len(sha) == 0 {
ctx.Error(400, "ref/sha not given", nil)
ctx.Error(400, "sha not given", nil)
return
}
status := &models.CommitStatus{
@@ -89,6 +85,23 @@ func GetCommitStatuses(ctx *context.APIContext) {
// description: sha of the commit
// type: string
// required: true
// - name: page
// in: query
// description: page number of results
// type: integer
// required: false
// - name: sort
// in: query
// description: type of sort
// type: string
// enum: [oldest, recentupdate, leastupdate, leastindex, highestindex]
// required: false
// - name: state
// in: query
// description: type of state
// type: string
// enum: [pending, success, error, failure, warning]
// required: false
// responses:
// "200":
// "$ref": "#/responses/StatusList"
@@ -118,10 +131,58 @@ func GetCommitStatusesByRef(ctx *context.APIContext) {
// description: name of branch/tag/commit
// type: string
// required: true
// - name: page
// in: query
// description: page number of results
// type: integer
// required: false
// - name: sort
// in: query
// description: type of sort
// type: string
// enum: [oldest, recentupdate, leastupdate, leastindex, highestindex]
// required: false
// - name: state
// in: query
// description: type of state
// type: string
// enum: [pending, success, error, failure, warning]
// required: false
// responses:
// "200":
// "$ref": "#/responses/StatusList"
getCommitStatuses(ctx, ctx.Params("ref"))
filter := ctx.Params("ref")
if len(filter) == 0 {
ctx.Error(400, "ref not given", nil)
return
}
for _, reftype := range []string{"heads", "tags"} { //Search branches and tags
refSHA, lastMethodName, err := searchRefCommitByType(ctx, reftype, filter)
if err != nil {
ctx.Error(500, lastMethodName, err)
return
}
if refSHA != "" {
filter = refSHA
break
}
}
getCommitStatuses(ctx, filter) //By default filter is maybe the raw SHA
}
func searchRefCommitByType(ctx *context.APIContext, refType, filter string) (string, string, error) {
refs, lastMethodName, err := getGitRefs(ctx, refType+"/"+filter) //Search by type
if err != nil {
return "", lastMethodName, err
}
if len(refs) > 0 {
return refs[0].Object.String(), "", nil //Return found SHA
}
return "", "", nil
}
func getCommitStatuses(ctx *context.APIContext, sha string) {
@@ -131,11 +192,13 @@ func getCommitStatuses(ctx *context.APIContext, sha string) {
}
repo := ctx.Repo.Repository
page := ctx.ParamsInt("page")
statuses, err := models.GetCommitStatuses(repo, sha, page)
statuses, _, err := models.GetCommitStatuses(repo, sha, &models.CommitStatusOptions{
Page: ctx.QueryInt("page"),
SortType: ctx.QueryTrim("sort"),
State: ctx.QueryTrim("state"),
})
if err != nil {
ctx.Error(500, "GetCommitStatuses", fmt.Errorf("GetCommitStatuses[%s, %s, %d]: %v", repo.FullName(), sha, page, err))
ctx.Error(500, "GetCommitStatuses", fmt.Errorf("GetCommitStatuses[%s, %s, %d]: %v", repo.FullName(), sha, ctx.QueryInt("page"), err))
return
}
@@ -180,6 +243,11 @@ func GetCombinedCommitStatusByRef(ctx *context.APIContext) {
// description: name of branch/tag/commit
// type: string
// required: true
// - name: page
// in: query
// description: page number of results
// type: integer
// required: false
// responses:
// "200":
// "$ref": "#/responses/Status"
@@ -190,7 +258,7 @@ func GetCombinedCommitStatusByRef(ctx *context.APIContext) {
}
repo := ctx.Repo.Repository
page := ctx.ParamsInt("page")
page := ctx.QueryInt("page")
statuses, err := models.GetLatestCommitStatus(repo, sha, page)
if err != nil {
+2 -2
View File
@@ -6,8 +6,8 @@ package repo
import (
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
)
// ListSubscribers list a repo's subscribers (i.e. watchers)
@@ -38,7 +38,7 @@ func ListSubscribers(ctx *context.APIContext) {
}
users := make([]*api.User, len(subscribers))
for i, subscriber := range subscribers {
users[i] = subscriber.APIFormat()
users[i] = convert.ToUser(subscriber, ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin)
}
ctx.JSON(200, users)
}
+4 -4
View File
@@ -5,11 +5,11 @@
package repo
import (
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/routers/api/v1/convert"
"net/http"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
)
// ListTags list all the tags of a repository
@@ -51,7 +51,7 @@ func ListTags(ctx *context.APIContext) {
func GetTag(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/git/tags/{sha} repository GetTag
// ---
// summary: Gets the tag of a repository.
// summary: Gets the tag object of an annotated tag (not lightweight tags)
// produces:
// - application/json
// parameters:
@@ -67,7 +67,7 @@ func GetTag(ctx *context.APIContext) {
// required: true
// - name: sha
// in: path
// description: sha of the tag
// description: sha of the tag. The Git tags API only supports annotated tag objects, not lightweight tags.
// type: string
// required: true
// responses:
+274
View File
@@ -0,0 +1,274 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package repo
import (
"net/http"
"strings"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
)
// ListTopics returns list of current topics for repo
func ListTopics(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/topics repository repoListTopics
// ---
// summary: Get list of topics that a repository has
// produces:
// - application/json
// parameters:
// - name: owner
// in: path
// description: owner of the repo
// type: string
// required: true
// - name: repo
// in: path
// description: name of the repo
// type: string
// required: true
// responses:
// "200":
// "$ref": "#/responses/TopicNames"
topics, err := models.FindTopics(&models.FindTopicOptions{
RepoID: ctx.Repo.Repository.ID,
})
if err != nil {
log.Error("ListTopics failed: %v", err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"message": "ListTopics failed.",
})
return
}
topicNames := make([]string, len(topics))
for i, topic := range topics {
topicNames[i] = topic.Name
}
ctx.JSON(http.StatusOK, map[string]interface{}{
"topics": topicNames,
})
}
// UpdateTopics updates repo with a new set of topics
func UpdateTopics(ctx *context.APIContext, form api.RepoTopicOptions) {
// swagger:operation PUT /repos/{owner}/{repo}/topics repository repoUpdateTopics
// ---
// summary: Replace list of topics for a repository
// produces:
// - application/json
// parameters:
// - name: owner
// in: path
// description: owner of the repo
// type: string
// required: true
// - name: repo
// in: path
// description: name of the repo
// type: string
// required: true
// - name: body
// in: body
// schema:
// "$ref": "#/definitions/RepoTopicOptions"
// responses:
// "204":
// "$ref": "#/responses/empty"
topicNames := form.Topics
validTopics, invalidTopics := models.SanitizeAndValidateTopics(topicNames)
if len(validTopics) > 25 {
ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{
"invalidTopics": nil,
"message": "Exceeding maximum number of topics per repo",
})
return
}
if len(invalidTopics) > 0 {
ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{
"invalidTopics": invalidTopics,
"message": "Topic names are invalid",
})
return
}
err := models.SaveTopics(ctx.Repo.Repository.ID, validTopics...)
if err != nil {
log.Error("SaveTopics failed: %v", err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"message": "Save topics failed.",
})
return
}
ctx.Status(http.StatusNoContent)
}
// AddTopic adds a topic name to a repo
func AddTopic(ctx *context.APIContext) {
// swagger:operation PUT /repos/{owner}/{repo}/topics/{topic} repository repoAddTopíc
// ---
// summary: Add a topic to a repository
// produces:
// - application/json
// parameters:
// - name: owner
// in: path
// description: owner of the repo
// type: string
// required: true
// - name: repo
// in: path
// description: name of the repo
// type: string
// required: true
// - name: topic
// in: path
// description: name of the topic to add
// type: string
// required: true
// responses:
// "204":
// "$ref": "#/responses/empty"
topicName := strings.TrimSpace(strings.ToLower(ctx.Params(":topic")))
if !models.ValidateTopic(topicName) {
ctx.Error(http.StatusUnprocessableEntity, "", "Topic name is invalid")
return
}
// Prevent adding more topics than allowed to repo
topics, err := models.FindTopics(&models.FindTopicOptions{
RepoID: ctx.Repo.Repository.ID,
})
if err != nil {
log.Error("AddTopic failed: %v", err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"message": "ListTopics failed.",
})
return
}
if len(topics) >= 25 {
ctx.JSON(http.StatusUnprocessableEntity, map[string]interface{}{
"message": "Exceeding maximum allowed topics per repo.",
})
return
}
_, err = models.AddTopic(ctx.Repo.Repository.ID, topicName)
if err != nil {
log.Error("AddTopic failed: %v", err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"message": "AddTopic failed.",
})
return
}
ctx.Status(http.StatusNoContent)
}
// DeleteTopic removes topic name from repo
func DeleteTopic(ctx *context.APIContext) {
// swagger:operation DELETE /repos/{owner}/{repo}/topics/{topic} repository repoDeleteTopic
// ---
// summary: Delete a topic from a repository
// produces:
// - application/json
// parameters:
// - name: owner
// in: path
// description: owner of the repo
// type: string
// required: true
// - name: repo
// in: path
// description: name of the repo
// type: string
// required: true
// - name: topic
// in: path
// description: name of the topic to delete
// type: string
// required: true
// responses:
// "204":
// "$ref": "#/responses/empty"
topicName := strings.TrimSpace(strings.ToLower(ctx.Params(":topic")))
if !models.ValidateTopic(topicName) {
ctx.Error(http.StatusUnprocessableEntity, "", "Topic name is invalid")
return
}
topic, err := models.DeleteTopic(ctx.Repo.Repository.ID, topicName)
if err != nil {
log.Error("DeleteTopic failed: %v", err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"message": "DeleteTopic failed.",
})
return
}
if topic == nil {
ctx.NotFound()
}
ctx.Status(http.StatusNoContent)
}
// TopicSearch search for creating topic
func TopicSearch(ctx *context.Context) {
// swagger:operation GET /topics/search repository topicSearch
// ---
// summary: search topics via keyword
// produces:
// - application/json
// parameters:
// - name: q
// in: query
// description: keywords to search
// required: true
// type: string
// responses:
// "200":
// "$ref": "#/responses/TopicListResponse"
if ctx.User == nil {
ctx.JSON(http.StatusForbidden, map[string]interface{}{
"message": "Only owners could change the topics.",
})
return
}
kw := ctx.Query("q")
topics, err := models.FindTopics(&models.FindTopicOptions{
Keyword: kw,
Limit: 10,
})
if err != nil {
log.Error("SearchTopics failed: %v", err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{
"message": "Search topics failed.",
})
return
}
topicResponses := make([]*api.TopicResponse, len(topics))
for i, topic := range topics {
topicResponses[i] = convert.ToTopicResponse(topic)
}
ctx.JSON(http.StatusOK, map[string]interface{}{
"topics": topicResponses,
})
}
+3
View File
@@ -117,4 +117,7 @@ type swaggerParameterBodies struct {
// in:body
DeleteFileOptions api.DeleteFileOptions
// in:body
RepoTopicOptions api.RepoTopicOptions
}
+43
View File
@@ -190,6 +190,35 @@ type swaggerCommit struct {
Body api.Commit `json:"body"`
}
// CommitList
// swagger:response CommitList
type swaggerCommitList struct {
// The current page
Page int `json:"X-Page"`
// Commits per page
PerPage int `json:"X-PerPage"`
// Total commit count
Total int `json:"X-Total"`
// Total number of pages
PageCount int `json:"X-PageCount"`
// True if there is another page
HasMore bool `json:"X-HasMore"`
//in: body
Body []api.Commit `json:"body"`
}
// EmptyRepository
// swagger:response EmptyRepository
type swaggerEmptyRepository struct {
//in: body
Body api.APIError `json:"body"`
}
// FileResponse
// swagger:response FileResponse
type swaggerFileResponse struct {
@@ -217,3 +246,17 @@ type swaggerFileDeleteResponse struct {
//in: body
Body api.FileDeleteResponse `json:"body"`
}
// TopicListResponse
// swagger:response TopicListResponse
type swaggerTopicListResponse struct {
//in: body
Body []api.TopicResponse `json:"body"`
}
// TopicNames
// swagger:response TopicNames
type swaggerTopicNames struct {
//in: body
Body api.TopicName `json:"body"`
}
+1 -8
View File
@@ -6,10 +6,9 @@
package user
import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
)
// ListAccessTokens list all the access tokens
@@ -36,9 +35,6 @@ func ListAccessTokens(ctx *context.APIContext) {
apiTokens := make([]*api.AccessToken, len(tokens))
for i := range tokens {
if tokens[i].Name == "drone" {
tokens[i].Name = "drone-legacy-use-oauth2-instead"
}
apiTokens[i] = &api.AccessToken{
ID: tokens[i].ID,
Name: tokens[i].Name,
@@ -79,9 +75,6 @@ func CreateAccessToken(ctx *context.APIContext, form api.CreateAccessTokenOption
UID: ctx.User.ID,
Name: form.Name,
}
if t.Name == "drone" {
t.Name = "drone-legacy-use-oauth2-instead"
}
if err := models.NewAccessToken(t); err != nil {
ctx.Error(500, "NewAccessToken", err)
return
+1 -2
View File
@@ -5,11 +5,10 @@
package user
import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
)
+3 -3
View File
@@ -5,16 +5,16 @@
package user
import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
)
func responseAPIUsers(ctx *context.APIContext, users []*models.User) {
apiUsers := make([]*api.User, len(users))
for i := range users {
apiUsers[i] = users[i].APIFormat()
apiUsers[i] = convert.ToUser(users[i], ctx.IsSigned, ctx.User != nil && ctx.User.IsAdmin)
}
ctx.JSON(200, &apiUsers)
}
+1 -2
View File
@@ -5,10 +5,9 @@
package user
import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
)
+3 -4
View File
@@ -5,11 +5,10 @@
package user
import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
"code.gitea.io/gitea/routers/api/v1/repo"
)
@@ -22,13 +21,13 @@ func appendPrivateInformation(apiKey *api.PublicKey, key *models.PublicKey, defa
apiKey.KeyType = "user"
if defaultUser.ID == key.OwnerID {
apiKey.Owner = defaultUser.APIFormat()
apiKey.Owner = convert.ToUser(defaultUser, true, true)
} else {
user, err := models.GetUserByID(key.OwnerID)
if err != nil {
return apiKey, err
}
apiKey.Owner = user.APIFormat()
apiKey.Owner = convert.ToUser(user, true, true)
}
} else {
apiKey.KeyType = "unknown"
+1 -2
View File
@@ -5,10 +5,9 @@
package user
import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
api "code.gitea.io/gitea/modules/structs"
)
// getStarredRepos returns the repos that the user with the specified userID has
+3 -7
View File
@@ -13,7 +13,7 @@ import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/routers/api/v1/convert"
"github.com/Unknwon/com"
"github.com/unknwon/com"
)
// Search search users
@@ -104,11 +104,7 @@ func GetInfo(ctx *context.APIContext) {
return
}
// Hide user e-mail when API caller isn't signed in.
if !ctx.IsSigned {
u.Email = ""
}
ctx.JSON(200, u.APIFormat())
ctx.JSON(200, convert.ToUser(u, ctx.IsSigned, ctx.User.ID == u.ID || ctx.User.IsAdmin))
}
// GetAuthenticatedUser get current user's information
@@ -121,7 +117,7 @@ func GetAuthenticatedUser(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/User"
ctx.JSON(200, ctx.User.APIFormat())
ctx.JSON(200, convert.ToUser(ctx.User, ctx.IsSigned, ctx.User != nil))
}
// GetUserHeatmapData is the handler to get a users heatmap
+1 -2
View File
@@ -5,11 +5,10 @@
package user
import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
)
// getWatchedRepos returns the repos that the user with the specified userID is
+3 -1
View File
@@ -15,7 +15,7 @@ import (
"code.gitea.io/gitea/routers/api/v1/convert"
"code.gitea.io/gitea/routers/utils"
"github.com/Unknwon/com"
"github.com/unknwon/com"
)
// GetOrgHook get an organization's webhook. If there is an error, write to
@@ -112,6 +112,7 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, orgID, repoID
Repository: com.IsSliceContainsStr(form.Events, string(models.HookEventRepository)),
Release: com.IsSliceContainsStr(form.Events, string(models.HookEventRelease)),
},
BranchFilter: form.BranchFilter,
},
IsActive: form.Active,
HookTaskType: models.ToHookTaskType(form.Type),
@@ -236,6 +237,7 @@ func editHook(ctx *context.APIContext, form *api.EditHookOption, w *models.Webho
w.PullRequest = com.IsSliceContainsStr(form.Events, string(models.HookEventPullRequest))
w.Repository = com.IsSliceContainsStr(form.Events, string(models.HookEventRepository))
w.Release = com.IsSliceContainsStr(form.Events, string(models.HookEventRelease))
w.BranchFilter = form.BranchFilter
if err := w.UpdateEvent(); err != nil {
ctx.Error(500, "UpdateEvent", err)