|
|
@@ -5,12 +5,15 @@ |
|
|
|
package repo |
|
|
|
|
|
|
|
import ( |
|
|
|
"fmt" |
|
|
|
"net/http" |
|
|
|
"strings" |
|
|
|
"time" |
|
|
|
|
|
|
|
"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/utils" |
|
|
|
) |
|
|
|
|
|
|
|
// ListTrackedTimes list all the tracked times of an issue |
|
|
@@ -37,6 +40,16 @@ func ListTrackedTimes(ctx *context.APIContext) { |
|
|
|
// type: integer |
|
|
|
// format: int64 |
|
|
|
// required: true |
|
|
|
// - name: since |
|
|
|
// in: query |
|
|
|
// description: Only show times updated after the given time. This is a timestamp in RFC 3339 format |
|
|
|
// type: string |
|
|
|
// format: date-time |
|
|
|
// - name: before |
|
|
|
// in: query |
|
|
|
// description: Only show times updated before the given time. This is a timestamp in RFC 3339 format |
|
|
|
// type: string |
|
|
|
// format: date-time |
|
|
|
// responses: |
|
|
|
// "200": |
|
|
|
// "$ref": "#/responses/TrackedTimeList" |
|
|
@@ -62,6 +75,11 @@ func ListTrackedTimes(ctx *context.APIContext) { |
|
|
|
IssueID: issue.ID, |
|
|
|
} |
|
|
|
|
|
|
|
if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = utils.GetQueryBeforeSince(ctx); err != nil { |
|
|
|
ctx.InternalServerError(err) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
if !ctx.IsUserRepoAdmin() && !ctx.User.IsAdmin { |
|
|
|
opts.UserID = ctx.User.ID |
|
|
|
} |
|
|
@@ -141,7 +159,7 @@ func AddTime(ctx *context.APIContext, form api.AddTimeOption) { |
|
|
|
//allow only RepoAdmin, Admin and User to add time |
|
|
|
user, err = models.GetUserByName(form.User) |
|
|
|
if err != nil { |
|
|
|
ctx.Error(500, "GetUserByName", err) |
|
|
|
ctx.Error(http.StatusInternalServerError, "GetUserByName", err) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@@ -195,33 +213,33 @@ func ResetIssueTime(ctx *context.APIContext) { |
|
|
|
// "400": |
|
|
|
// "$ref": "#/responses/error" |
|
|
|
// "403": |
|
|
|
// "$ref": "#/responses/error" |
|
|
|
// "$ref": "#/responses/forbidden" |
|
|
|
|
|
|
|
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) |
|
|
|
if err != nil { |
|
|
|
if models.IsErrIssueNotExist(err) { |
|
|
|
ctx.NotFound(err) |
|
|
|
} else { |
|
|
|
ctx.Error(500, "GetIssueByIndex", err) |
|
|
|
ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) |
|
|
|
} |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
if !ctx.Repo.CanUseTimetracker(issue, ctx.User) { |
|
|
|
if !ctx.Repo.Repository.IsTimetrackerEnabled() { |
|
|
|
ctx.JSON(400, struct{ Message string }{Message: "time tracking disabled"}) |
|
|
|
ctx.JSON(http.StatusBadRequest, struct{ Message string }{Message: "time tracking disabled"}) |
|
|
|
return |
|
|
|
} |
|
|
|
ctx.Status(403) |
|
|
|
ctx.Status(http.StatusForbidden) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
err = models.DeleteIssueUserTimes(issue, ctx.User) |
|
|
|
if err != nil { |
|
|
|
if models.IsErrNotExist(err) { |
|
|
|
ctx.Error(404, "DeleteIssueUserTimes", err) |
|
|
|
ctx.Error(http.StatusNotFound, "DeleteIssueUserTimes", err) |
|
|
|
} else { |
|
|
|
ctx.Error(500, "DeleteIssueUserTimes", err) |
|
|
|
ctx.Error(http.StatusInternalServerError, "DeleteIssueUserTimes", err) |
|
|
|
} |
|
|
|
return |
|
|
|
} |
|
|
@@ -266,52 +284,53 @@ func DeleteTime(ctx *context.APIContext) { |
|
|
|
// "400": |
|
|
|
// "$ref": "#/responses/error" |
|
|
|
// "403": |
|
|
|
// "$ref": "#/responses/error" |
|
|
|
// "$ref": "#/responses/forbidden" |
|
|
|
|
|
|
|
issue, err := models.GetIssueByIndex(ctx.Repo.Repository.ID, ctx.ParamsInt64(":index")) |
|
|
|
if err != nil { |
|
|
|
if models.IsErrIssueNotExist(err) { |
|
|
|
ctx.NotFound(err) |
|
|
|
} else { |
|
|
|
ctx.Error(500, "GetIssueByIndex", err) |
|
|
|
ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err) |
|
|
|
} |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
if !ctx.Repo.CanUseTimetracker(issue, ctx.User) { |
|
|
|
if !ctx.Repo.Repository.IsTimetrackerEnabled() { |
|
|
|
ctx.JSON(400, struct{ Message string }{Message: "time tracking disabled"}) |
|
|
|
ctx.JSON(http.StatusBadRequest, struct{ Message string }{Message: "time tracking disabled"}) |
|
|
|
return |
|
|
|
} |
|
|
|
ctx.Status(403) |
|
|
|
ctx.Status(http.StatusForbidden) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
time, err := models.GetTrackedTimeByID(ctx.ParamsInt64(":id")) |
|
|
|
if err != nil { |
|
|
|
ctx.Error(500, "GetTrackedTimeByID", err) |
|
|
|
ctx.Error(http.StatusInternalServerError, "GetTrackedTimeByID", err) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
if !ctx.User.IsAdmin && time.UserID != ctx.User.ID { |
|
|
|
//Only Admin and User itself can delete their time |
|
|
|
ctx.Status(403) |
|
|
|
ctx.Status(http.StatusForbidden) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
err = models.DeleteTime(time) |
|
|
|
if err != nil { |
|
|
|
ctx.Error(500, "DeleteTime", err) |
|
|
|
ctx.Error(http.StatusInternalServerError, "DeleteTime", err) |
|
|
|
return |
|
|
|
} |
|
|
|
ctx.Status(204) |
|
|
|
ctx.Status(http.StatusNoContent) |
|
|
|
} |
|
|
|
|
|
|
|
// ListTrackedTimesByUser lists all tracked times of the user |
|
|
|
func ListTrackedTimesByUser(ctx *context.APIContext) { |
|
|
|
// swagger:operation GET /repos/{owner}/{repo}/times/{user} user userTrackedTimes |
|
|
|
// swagger:operation GET /repos/{owner}/{repo}/times/{user} repository userTrackedTimes |
|
|
|
// --- |
|
|
|
// summary: List a user's tracked times in a repo |
|
|
|
// deprecated: true |
|
|
|
// produces: |
|
|
|
// - application/json |
|
|
|
// parameters: |
|
|
@@ -335,6 +354,8 @@ func ListTrackedTimesByUser(ctx *context.APIContext) { |
|
|
|
// "$ref": "#/responses/TrackedTimeList" |
|
|
|
// "400": |
|
|
|
// "$ref": "#/responses/error" |
|
|
|
// "403": |
|
|
|
// "$ref": "#/responses/forbidden" |
|
|
|
|
|
|
|
if !ctx.Repo.Repository.IsTimetrackerEnabled() { |
|
|
|
ctx.Error(http.StatusBadRequest, "", "time tracking disabled") |
|
|
@@ -353,9 +374,23 @@ func ListTrackedTimesByUser(ctx *context.APIContext) { |
|
|
|
ctx.NotFound() |
|
|
|
return |
|
|
|
} |
|
|
|
trackedTimes, err := models.GetTrackedTimes(models.FindTrackedTimesOptions{ |
|
|
|
|
|
|
|
if !ctx.IsUserRepoAdmin() && !ctx.User.IsAdmin && ctx.User.ID != user.ID { |
|
|
|
ctx.Error(http.StatusForbidden, "", fmt.Errorf("query user not allowed not enouth rights")) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
if !ctx.IsUserRepoAdmin() && !ctx.User.IsAdmin && ctx.User.ID != user.ID { |
|
|
|
ctx.Error(http.StatusForbidden, "", fmt.Errorf("query user not allowed not enouth rights")) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
opts := models.FindTrackedTimesOptions{ |
|
|
|
UserID: user.ID, |
|
|
|
RepositoryID: ctx.Repo.Repository.ID}) |
|
|
|
RepositoryID: ctx.Repo.Repository.ID, |
|
|
|
} |
|
|
|
|
|
|
|
trackedTimes, err := models.GetTrackedTimes(opts) |
|
|
|
if err != nil { |
|
|
|
ctx.Error(http.StatusInternalServerError, "GetTrackedTimes", err) |
|
|
|
return |
|
|
@@ -385,11 +420,27 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) { |
|
|
|
// description: name of the repo |
|
|
|
// type: string |
|
|
|
// required: true |
|
|
|
// - name: user |
|
|
|
// in: query |
|
|
|
// description: optional filter by user |
|
|
|
// type: string |
|
|
|
// - name: since |
|
|
|
// in: query |
|
|
|
// description: Only show times updated after the given time. This is a timestamp in RFC 3339 format |
|
|
|
// type: string |
|
|
|
// format: date-time |
|
|
|
// - name: before |
|
|
|
// in: query |
|
|
|
// description: Only show times updated before the given time. This is a timestamp in RFC 3339 format |
|
|
|
// type: string |
|
|
|
// format: date-time |
|
|
|
// responses: |
|
|
|
// "200": |
|
|
|
// "$ref": "#/responses/TrackedTimeList" |
|
|
|
// "400": |
|
|
|
// "$ref": "#/responses/error" |
|
|
|
// "403": |
|
|
|
// "$ref": "#/responses/forbidden" |
|
|
|
|
|
|
|
if !ctx.Repo.Repository.IsTimetrackerEnabled() { |
|
|
|
ctx.Error(http.StatusBadRequest, "", "time tracking disabled") |
|
|
@@ -400,8 +451,30 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) { |
|
|
|
RepositoryID: ctx.Repo.Repository.ID, |
|
|
|
} |
|
|
|
|
|
|
|
// Filters |
|
|
|
qUser := strings.Trim(ctx.Query("user"), " ") |
|
|
|
if qUser != "" { |
|
|
|
user, err := models.GetUserByName(qUser) |
|
|
|
if err != nil { |
|
|
|
ctx.Error(http.StatusInternalServerError, "GetUserByName", err) |
|
|
|
return |
|
|
|
} |
|
|
|
opts.UserID = user.ID |
|
|
|
} |
|
|
|
|
|
|
|
var err error |
|
|
|
if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = utils.GetQueryBeforeSince(ctx); err != nil { |
|
|
|
ctx.InternalServerError(err) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
if !ctx.IsUserRepoAdmin() && !ctx.User.IsAdmin { |
|
|
|
opts.UserID = ctx.User.ID |
|
|
|
if opts.UserID == 0 { |
|
|
|
opts.UserID = ctx.User.ID |
|
|
|
} else { |
|
|
|
ctx.Error(http.StatusForbidden, "", fmt.Errorf("query user not allowed not enouth rights")) |
|
|
|
return |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
trackedTimes, err := models.GetTrackedTimes(opts) |
|
|
@@ -423,18 +496,39 @@ func ListMyTrackedTimes(ctx *context.APIContext) { |
|
|
|
// summary: List the current user's tracked times |
|
|
|
// produces: |
|
|
|
// - application/json |
|
|
|
// parameters: |
|
|
|
// - name: since |
|
|
|
// in: query |
|
|
|
// description: Only show times updated after the given time. This is a timestamp in RFC 3339 format |
|
|
|
// type: string |
|
|
|
// format: date-time |
|
|
|
// - name: before |
|
|
|
// in: query |
|
|
|
// description: Only show times updated before the given time. This is a timestamp in RFC 3339 format |
|
|
|
// type: string |
|
|
|
// format: date-time |
|
|
|
// responses: |
|
|
|
// "200": |
|
|
|
// "$ref": "#/responses/TrackedTimeList" |
|
|
|
|
|
|
|
trackedTimes, err := models.GetTrackedTimes(models.FindTrackedTimesOptions{UserID: ctx.User.ID}) |
|
|
|
opts := models.FindTrackedTimesOptions{UserID: ctx.User.ID} |
|
|
|
|
|
|
|
var err error |
|
|
|
if opts.CreatedBeforeUnix, opts.CreatedAfterUnix, err = utils.GetQueryBeforeSince(ctx); err != nil { |
|
|
|
ctx.InternalServerError(err) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
trackedTimes, err := models.GetTrackedTimes(opts) |
|
|
|
if err != nil { |
|
|
|
ctx.Error(http.StatusInternalServerError, "GetTrackedTimesByUser", err) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
if err = trackedTimes.LoadAttributes(); err != nil { |
|
|
|
ctx.Error(http.StatusInternalServerError, "LoadAttributes", err) |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
ctx.JSON(http.StatusOK, trackedTimes.APIFormat()) |
|
|
|
} |