From 71bb6df75ae541687c64f5e6e4da16ea9e95acfe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kim=20=22BKC=22=20Carlb=C3=A4cker?=
 <kim.carlbacker@gmail.com>
Date: Mon, 3 Oct 2016 12:35:42 +0200
Subject: [PATCH 1/3] Add undocumented endpoint for /repositories/:id

---
 routers/api/v1/api.go       |  2 ++
 routers/api/v1/repo/repo.go | 15 +++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index 95bdfd072e..506a615624 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -243,6 +243,8 @@ func RegisterRoutes(m *macaron.Macaron) {
 			m.Get("/search", repo.Search)
 		})
 
+		m.Combo("/repositories/:id", reqToken()).Get(repo.GetByID)
+
 		m.Group("/repos", func() {
 			m.Post("/migrate", bind(auth.MigrateRepoForm{}), repo.Migrate)
 			m.Combo("/:username/:reponame", context.ExtractOwnerAndRepo()).
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index 1fa0b14b40..33d474ebd8 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -251,6 +251,21 @@ func Get(ctx *context.APIContext) {
 	ctx.JSON(200, repo.APIFormat(&api.Permission{true, true, true}))
 }
 
+// GetByID returns a single Repository
+func GetByID(ctx *context.APIContext) {
+	repo, err := models.GetRepositoryByID(ctx.ParamsInt64(":id"))
+	if err != nil {
+		if models.IsErrRepoNotExist(err) {
+			ctx.Status(404)
+		} else {
+			ctx.Error(500, "GetRepositoryByID", err)
+		}
+		return
+	}
+
+	ctx.JSON(200, repo.APIFormat(&api.Permission{true, true, true}))
+}
+
 // Delete delete one repository
 // see https://github.com/gogits/go-gogs-client/wiki/Repositories#delete
 func Delete(ctx *context.APIContext) {

From e6cfccdd40397b95dcf3de0ea9b484feea954fc2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kim=20=22BKC=22=20Carlb=C3=A4cker?=
 <kim.carlbacker@gmail.com>
Date: Fri, 7 Oct 2016 19:17:27 +0200
Subject: [PATCH 2/3] GitHub API Compliance (& linting)

---
 models/issue_label.go        | 28 +++++++++++++++++++++++++++-
 modules/auth/auth.go         |  3 +++
 routers/api/v1/repo/issue.go | 20 ++++++++++++++++----
 routers/api/v1/repo/label.go | 13 ++++++++++++-
 routers/api/v1/repo/repo.go  |  6 +++---
 5 files changed, 61 insertions(+), 9 deletions(-)

diff --git a/models/issue_label.go b/models/issue_label.go
index befe3f192a..ffdaa072c8 100644
--- a/models/issue_label.go
+++ b/models/issue_label.go
@@ -67,7 +67,7 @@ func (label *Label) APIFormat() *api.Label {
 	return &api.Label{
 		ID:    label.ID,
 		Name:  label.Name,
-		Color: label.Color,
+		Color: strings.TrimLeft(label.Color, "#"),
 	}
 }
 
@@ -102,6 +102,27 @@ func NewLabels(labels ...*Label) error {
 	return err
 }
 
+// getLabelInRepoByName returns a label by Name in given repository.
+// If pass repoID as 0, then ORM will ignore limitation of repository
+// and can return arbitrary label with any valid ID.
+func getLabelInRepoByName(e Engine, repoID int64, labelName string) (*Label, error) {
+	if len(labelName) <= 0 {
+		return nil, ErrLabelNotExist{0, repoID}
+	}
+
+	l := &Label{
+		Name:   labelName,
+		RepoID: repoID,
+	}
+	has, err := x.Get(l)
+	if err != nil {
+		return nil, err
+	} else if !has {
+		return nil, ErrLabelNotExist{0, l.RepoID}
+	}
+	return l, nil
+}
+
 // getLabelInRepoByID returns a label by ID in given repository.
 // If pass repoID as 0, then ORM will ignore limitation of repository
 // and can return arbitrary label with any valid ID.
@@ -129,6 +150,11 @@ func GetLabelByID(id int64) (*Label, error) {
 }
 
 // GetLabelInRepoByID returns a label by ID in given repository.
+func GetLabelInRepoByName(repoID int64, labelName string) (*Label, error) {
+	return getLabelInRepoByName(x, repoID, labelName)
+}
+
+// GetLabelInRepoByID returns a label by ID in given repository.
 func GetLabelInRepoByID(repoID, labelID int64) (*Label, error) {
 	return getLabelInRepoByID(x, repoID, labelID)
 }
diff --git a/modules/auth/auth.go b/modules/auth/auth.go
index ed94d0a698..811f890746 100644
--- a/modules/auth/auth.go
+++ b/modules/auth/auth.go
@@ -35,6 +35,9 @@ func SignedInID(ctx *macaron.Context, sess session.Store) int64 {
 	// Check access token.
 	if IsAPIPath(ctx.Req.URL.Path) {
 		tokenSHA := ctx.Query("token")
+		if len(tokenSHA) <= 0 {
+			tokenSHA = ctx.Query("access_token")
+		}
 		if len(tokenSHA) == 0 {
 			// Well, check with header again.
 			auHead := ctx.Req.Header.Get("Authorization")
diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go
index 462aca88ad..8501334ade 100644
--- a/routers/api/v1/repo/issue.go
+++ b/routers/api/v1/repo/issue.go
@@ -17,14 +17,26 @@ import (
 
 // ListIssues list the issues of a repository
 func ListIssues(ctx *context.APIContext) {
-	issues, err := models.Issues(&models.IssuesOptions{
-		RepoID: ctx.Repo.Repository.ID,
-		Page:   ctx.QueryInt("page"),
-	})
+	issueOpts := models.IssuesOptions{
+		RepoID:   ctx.Repo.Repository.ID,
+		Page:     ctx.QueryInt("page"),
+		IsClosed: ctx.Query("state") == "closed",
+	}
+
+	issues, err := models.Issues(&issueOpts)
 	if err != nil {
 		ctx.Error(500, "Issues", err)
 		return
 	}
+	if ctx.Query("state") == "all" {
+		issueOpts.IsClosed = !issueOpts.IsClosed
+		temp_issues, err := models.Issues(&issueOpts)
+		if err != nil {
+			ctx.Error(500, "Issues", err)
+			return
+		}
+		issues = append(issues, temp_issues...)
+	}
 
 	// FIXME: use IssueList to improve performance.
 	apiIssues := make([]*api.Issue, len(issues))
diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go
index 383868beda..a2bf3a9e40 100644
--- a/routers/api/v1/repo/label.go
+++ b/routers/api/v1/repo/label.go
@@ -5,6 +5,8 @@
 package repo
 
 import (
+	"strconv"
+
 	api "code.gitea.io/sdk/gitea"
 
 	"code.gitea.io/gitea/models"
@@ -28,7 +30,16 @@ func ListLabels(ctx *context.APIContext) {
 
 // GetLabel get label by repository and label id
 func GetLabel(ctx *context.APIContext) {
-	label, err := models.GetLabelInRepoByID(ctx.Repo.Repository.ID, ctx.ParamsInt64(":id"))
+	var (
+		label *models.Label
+		err   error
+	)
+	strID := ctx.Params(":id")
+	if intID, err2 := strconv.ParseInt(strID, 10, 64); err2 != nil {
+		label, err = models.GetLabelInRepoByName(ctx.Repo.Repository.ID, strID)
+	} else {
+		label, err = models.GetLabelInRepoByID(ctx.Repo.Repository.ID, intID)
+	}
 	if err != nil {
 		if models.IsErrLabelNotExist(err) {
 			ctx.Status(404)
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index 33d474ebd8..0c5c1ef5fd 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -141,7 +141,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *models.User, opt api.CreateR
 	ctx.JSON(201, repo.APIFormat(&api.Permission{true, true, true}))
 }
 
-// Create create one repository of mine
+// Create one repository of mine
 // see https://github.com/gogits/go-gogs-client/wiki/Repositories#create
 func Create(ctx *context.APIContext, opt api.CreateRepoOption) {
 	// Shouldn't reach this condition, but just in case.
@@ -244,7 +244,7 @@ func Migrate(ctx *context.APIContext, form auth.MigrateRepoForm) {
 	ctx.JSON(201, repo.APIFormat(&api.Permission{true, true, true}))
 }
 
-// Get get one repository
+// Get one repository
 // see https://github.com/gogits/go-gogs-client/wiki/Repositories#get
 func Get(ctx *context.APIContext) {
 	repo := ctx.Repo.Repository
@@ -266,7 +266,7 @@ func GetByID(ctx *context.APIContext) {
 	ctx.JSON(200, repo.APIFormat(&api.Permission{true, true, true}))
 }
 
-// Delete delete one repository
+// Delete one repository
 // see https://github.com/gogits/go-gogs-client/wiki/Repositories#delete
 func Delete(ctx *context.APIContext) {
 	owner := ctx.Repo.Owner

From e8e0539b454d622c1c428d03ac9c6f40d2654600 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kim=20=22BKC=22=20Carlb=C3=A4cker?=
 <kim.carlbacker@gmail.com>
Date: Fri, 2 Dec 2016 09:28:45 +0100
Subject: [PATCH 3/3] Linting

---
 models/issue_label.go        | 2 +-
 routers/api/v1/repo/issue.go | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/models/issue_label.go b/models/issue_label.go
index ffdaa072c8..39805ba80d 100644
--- a/models/issue_label.go
+++ b/models/issue_label.go
@@ -149,7 +149,7 @@ func GetLabelByID(id int64) (*Label, error) {
 	return getLabelInRepoByID(x, 0, id)
 }
 
-// GetLabelInRepoByID returns a label by ID in given repository.
+// GetLabelInRepoByName returns a label by name in given repository.
 func GetLabelInRepoByName(repoID int64, labelName string) (*Label, error) {
 	return getLabelInRepoByName(x, repoID, labelName)
 }
diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go
index 8501334ade..908b5aeb96 100644
--- a/routers/api/v1/repo/issue.go
+++ b/routers/api/v1/repo/issue.go
@@ -30,12 +30,12 @@ func ListIssues(ctx *context.APIContext) {
 	}
 	if ctx.Query("state") == "all" {
 		issueOpts.IsClosed = !issueOpts.IsClosed
-		temp_issues, err := models.Issues(&issueOpts)
+		tempIssues, err := models.Issues(&issueOpts)
 		if err != nil {
 			ctx.Error(500, "Issues", err)
 			return
 		}
-		issues = append(issues, temp_issues...)
+		issues = append(issues, tempIssues...)
 	}
 
 	// FIXME: use IssueList to improve performance.