summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKN4CK3R <admin@oldschoolhack.me>2022-03-26 10:04:22 +0100
committerGitHub <noreply@github.com>2022-03-26 17:04:22 +0800
commit59b867dc2dfc1ecb0ee703ff44e1be9c5c53cf86 (patch)
tree7114b991554e6e7dcb4123c0aa365c674d8411a0
parentf36701c702dc67011999cfaaf37e002c13e7a87e (diff)
downloadgitea-59b867dc2dfc1ecb0ee703ff44e1be9c5c53cf86.tar.gz
gitea-59b867dc2dfc1ecb0ee703ff44e1be9c5c53cf86.zip
Add `ContextUser` to http request context (#18798)
This PR adds a middleware which sets a ContextUser (like GetUserByParams before) in a single place which can be used by other methods. For routes which represent a repo or org the respective middlewares set the field too. Also fix a bug in modules/context/org.go during refactoring.
-rw-r--r--integrations/api_user_org_perm_test.go2
-rw-r--r--modules/context/context.go5
-rw-r--r--modules/context/org.go3
-rw-r--r--modules/context/repo.go1
-rw-r--r--routers/api/v1/admin/org.go8
-rw-r--r--routers/api/v1/admin/repo.go8
-rw-r--r--routers/api/v1/admin/user.go82
-rw-r--r--routers/api/v1/api.go17
-rw-r--r--routers/api/v1/org/org.go17
-rw-r--r--routers/api/v1/user/follower.go42
-rw-r--r--routers/api/v1/user/gpg_key.go6
-rw-r--r--routers/api/v1/user/key.go6
-rw-r--r--routers/api/v1/user/repo.go6
-rw-r--r--routers/api/v1/user/star.go7
-rw-r--r--routers/api/v1/user/user.go17
-rw-r--r--routers/api/v1/user/watch.go5
-rw-r--r--routers/web/feed/profile.go25
-rw-r--r--routers/web/repo/http.go15
-rw-r--r--routers/web/user/home.go8
-rw-r--r--routers/web/user/profile.go136
-rw-r--r--routers/web/web.go18
-rw-r--r--services/context/user.go62
-rw-r--r--templates/swagger/v1_json.tmpl66
23 files changed, 243 insertions, 319 deletions
diff --git a/integrations/api_user_org_perm_test.go b/integrations/api_user_org_perm_test.go
index 0dcdbd77ad..f4047e72be 100644
--- a/integrations/api_user_org_perm_test.go
+++ b/integrations/api_user_org_perm_test.go
@@ -133,7 +133,7 @@ func TestUnknowUser(t *testing.T) {
var apiError api.APIError
DecodeJSON(t, resp, &apiError)
- assert.Equal(t, "GetUserByName", apiError.Message)
+ assert.Equal(t, "user redirect does not exist [name: unknow]", apiError.Message)
}
func TestUnknowOrganization(t *testing.T) {
diff --git a/modules/context/context.go b/modules/context/context.go
index 6cd503984f..eb0edef394 100644
--- a/modules/context/context.go
+++ b/modules/context/context.go
@@ -67,8 +67,9 @@ type Context struct {
IsSigned bool
IsBasicAuth bool
- Repo *Repository
- Org *Organization
+ ContextUser *user_model.User
+ Repo *Repository
+ Org *Organization
}
// TrHTMLEscapeArgs runs Tr but pre-escapes all arguments with html.EscapeString.
diff --git a/modules/context/org.go b/modules/context/org.go
index a1080fc0fb..8e292fa1c5 100644
--- a/modules/context/org.go
+++ b/modules/context/org.go
@@ -53,7 +53,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
var err error
ctx.Org.Organization, err = models.GetOrgByName(orgName)
if err != nil {
- if user_model.IsErrUserNotExist(err) {
+ if models.IsErrOrgNotExist(err) {
redirectUserID, err := user_model.LookupUserRedirect(orgName)
if err == nil {
RedirectToUser(ctx, orgName, redirectUserID)
@@ -68,6 +68,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
return
}
org := ctx.Org.Organization
+ ctx.ContextUser = org.AsUser()
ctx.Data["Org"] = org
teams, err := org.LoadTeams()
diff --git a/modules/context/repo.go b/modules/context/repo.go
index b345decf7e..ccdc810fb6 100644
--- a/modules/context/repo.go
+++ b/modules/context/repo.go
@@ -439,6 +439,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) {
}
}
ctx.Repo.Owner = owner
+ ctx.ContextUser = owner
ctx.Data["Username"] = ctx.Repo.Owner.Name
// redirect link to wiki
diff --git a/routers/api/v1/admin/org.go b/routers/api/v1/admin/org.go
index 4ebfe9863c..e4850ac494 100644
--- a/routers/api/v1/admin/org.go
+++ b/routers/api/v1/admin/org.go
@@ -15,7 +15,6 @@ import (
"code.gitea.io/gitea/modules/convert"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/user"
"code.gitea.io/gitea/routers/api/v1/utils"
)
@@ -45,11 +44,8 @@ func CreateOrg(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "422":
// "$ref": "#/responses/validationError"
+
form := web.GetForm(ctx).(*api.CreateOrgOption)
- u := user.GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
visibility := api.VisibleTypePublic
if form.Visibility != "" {
@@ -67,7 +63,7 @@ func CreateOrg(ctx *context.APIContext) {
Visibility: visibility,
}
- if err := models.CreateOrganization(org, u); err != nil {
+ if err := models.CreateOrganization(org, ctx.ContextUser); err != nil {
if user_model.IsErrUserAlreadyExist(err) ||
db.IsErrNameReserved(err) ||
db.IsErrNameCharsNotAllowed(err) ||
diff --git a/routers/api/v1/admin/repo.go b/routers/api/v1/admin/repo.go
index 467f8a22ff..712ced89c9 100644
--- a/routers/api/v1/admin/repo.go
+++ b/routers/api/v1/admin/repo.go
@@ -9,7 +9,6 @@ import (
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/repo"
- "code.gitea.io/gitea/routers/api/v1/user"
)
// CreateRepo api for creating a repository
@@ -42,11 +41,8 @@ func CreateRepo(ctx *context.APIContext) {
// "$ref": "#/responses/error"
// "422":
// "$ref": "#/responses/validationError"
+
form := web.GetForm(ctx).(*api.CreateRepoOption)
- owner := user.GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
- repo.CreateUserRepo(ctx, owner, *form)
+ repo.CreateUserRepo(ctx, ctx.ContextUser, *form)
}
diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go
index 677950664d..da44c23213 100644
--- a/routers/api/v1/admin/user.go
+++ b/routers/api/v1/admin/user.go
@@ -73,6 +73,7 @@ func CreateUser(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "422":
// "$ref": "#/responses/validationError"
+
form := web.GetForm(ctx).(*api.CreateUserOption)
u := &user_model.User{
@@ -163,13 +164,10 @@ func EditUser(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "422":
// "$ref": "#/responses/validationError"
+
form := web.GetForm(ctx).(*api.EditUserOption)
- u := user.GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
- parseAuthSource(ctx, u, form.SourceID, form.LoginName)
+ parseAuthSource(ctx, ctx.ContextUser, form.SourceID, form.LoginName)
if ctx.Written() {
return
}
@@ -193,24 +191,24 @@ func EditUser(ctx *context.APIContext) {
ctx.Error(http.StatusBadRequest, "PasswordPwned", errors.New("PasswordPwned"))
return
}
- if u.Salt, err = user_model.GetUserSalt(); err != nil {
+ if ctx.ContextUser.Salt, err = user_model.GetUserSalt(); err != nil {
ctx.Error(http.StatusInternalServerError, "UpdateUser", err)
return
}
- if err = u.SetPassword(form.Password); err != nil {
+ if err = ctx.ContextUser.SetPassword(form.Password); err != nil {
ctx.InternalServerError(err)
return
}
}
if form.MustChangePassword != nil {
- u.MustChangePassword = *form.MustChangePassword
+ ctx.ContextUser.MustChangePassword = *form.MustChangePassword
}
- u.LoginName = form.LoginName
+ ctx.ContextUser.LoginName = form.LoginName
if form.FullName != nil {
- u.FullName = *form.FullName
+ ctx.ContextUser.FullName = *form.FullName
}
var emailChanged bool
if form.Email != nil {
@@ -225,47 +223,47 @@ func EditUser(ctx *context.APIContext) {
return
}
- emailChanged = !strings.EqualFold(u.Email, email)
- u.Email = email
+ emailChanged = !strings.EqualFold(ctx.ContextUser.Email, email)
+ ctx.ContextUser.Email = email
}
if form.Website != nil {
- u.Website = *form.Website
+ ctx.ContextUser.Website = *form.Website
}
if form.Location != nil {
- u.Location = *form.Location
+ ctx.ContextUser.Location = *form.Location
}
if form.Description != nil {
- u.Description = *form.Description
+ ctx.ContextUser.Description = *form.Description
}
if form.Active != nil {
- u.IsActive = *form.Active
+ ctx.ContextUser.IsActive = *form.Active
}
if len(form.Visibility) != 0 {
- u.Visibility = api.VisibilityModes[form.Visibility]
+ ctx.ContextUser.Visibility = api.VisibilityModes[form.Visibility]
}
if form.Admin != nil {
- u.IsAdmin = *form.Admin
+ ctx.ContextUser.IsAdmin = *form.Admin
}
if form.AllowGitHook != nil {
- u.AllowGitHook = *form.AllowGitHook
+ ctx.ContextUser.AllowGitHook = *form.AllowGitHook
}
if form.AllowImportLocal != nil {
- u.AllowImportLocal = *form.AllowImportLocal
+ ctx.ContextUser.AllowImportLocal = *form.AllowImportLocal
}
if form.MaxRepoCreation != nil {
- u.MaxRepoCreation = *form.MaxRepoCreation
+ ctx.ContextUser.MaxRepoCreation = *form.MaxRepoCreation
}
if form.AllowCreateOrganization != nil {
- u.AllowCreateOrganization = *form.AllowCreateOrganization
+ ctx.ContextUser.AllowCreateOrganization = *form.AllowCreateOrganization
}
if form.ProhibitLogin != nil {
- u.ProhibitLogin = *form.ProhibitLogin
+ ctx.ContextUser.ProhibitLogin = *form.ProhibitLogin
}
if form.Restricted != nil {
- u.IsRestricted = *form.Restricted
+ ctx.ContextUser.IsRestricted = *form.Restricted
}
- if err := user_model.UpdateUser(u, emailChanged); err != nil {
+ if err := user_model.UpdateUser(ctx.ContextUser, emailChanged); err != nil {
if user_model.IsErrEmailAlreadyUsed(err) ||
user_model.IsErrEmailCharIsNotSupported(err) ||
user_model.IsErrEmailInvalid(err) {
@@ -275,9 +273,9 @@ func EditUser(ctx *context.APIContext) {
}
return
}
- log.Trace("Account profile updated by admin (%s): %s", ctx.Doer.Name, u.Name)
+ log.Trace("Account profile updated by admin (%s): %s", ctx.Doer.Name, ctx.ContextUser.Name)
- ctx.JSON(http.StatusOK, convert.ToUser(u, ctx.Doer))
+ ctx.JSON(http.StatusOK, convert.ToUser(ctx.ContextUser, ctx.Doer))
}
// DeleteUser api for deleting a user
@@ -301,17 +299,12 @@ func DeleteUser(ctx *context.APIContext) {
// "422":
// "$ref": "#/responses/validationError"
- u := user.GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
-
- if u.IsOrganization() {
- ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("%s is an organization not a user", u.Name))
+ if ctx.ContextUser.IsOrganization() {
+ ctx.Error(http.StatusUnprocessableEntity, "", fmt.Errorf("%s is an organization not a user", ctx.ContextUser.Name))
return
}
- if err := user_service.DeleteUser(u); err != nil {
+ if err := user_service.DeleteUser(ctx.ContextUser); err != nil {
if models.IsErrUserOwnRepos(err) ||
models.IsErrUserHasOrgs(err) {
ctx.Error(http.StatusUnprocessableEntity, "", err)
@@ -320,7 +313,7 @@ func DeleteUser(ctx *context.APIContext) {
}
return
}
- log.Trace("Account deleted by admin(%s): %s", ctx.Doer.Name, u.Name)
+ log.Trace("Account deleted by admin(%s): %s", ctx.Doer.Name, ctx.ContextUser.Name)
ctx.Status(http.StatusNoContent)
}
@@ -351,12 +344,10 @@ func CreatePublicKey(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "422":
// "$ref": "#/responses/validationError"
+
form := web.GetForm(ctx).(*api.CreateKeyOption)
- u := user.GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
- user.CreateUserPublicKey(ctx, *form, u.ID)
+
+ user.CreateUserPublicKey(ctx, *form, ctx.ContextUser.ID)
}
// DeleteUserPublicKey api for deleting a user's public key
@@ -386,12 +377,7 @@ func DeleteUserPublicKey(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- u := user.GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
-
- if err := asymkey_service.DeletePublicKey(u, ctx.ParamsInt64(":id")); err != nil {
+ if err := asymkey_service.DeletePublicKey(ctx.ContextUser, ctx.ParamsInt64(":id")); err != nil {
if asymkey_model.IsErrKeyNotExist(err) {
ctx.NotFound()
} else if asymkey_model.IsErrKeyAccessDenied(err) {
@@ -401,7 +387,7 @@ func DeleteUserPublicKey(ctx *context.APIContext) {
}
return
}
- log.Trace("Key deleted by admin(%s): %s", ctx.Doer.Name, u.Name)
+ log.Trace("Key deleted by admin(%s): %s", ctx.Doer.Name, ctx.ContextUser.Name)
ctx.Status(http.StatusNoContent)
}
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index 4b30164026..5ac6fba29b 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -87,6 +87,7 @@ import (
"code.gitea.io/gitea/routers/api/v1/settings"
"code.gitea.io/gitea/routers/api/v1/user"
"code.gitea.io/gitea/services/auth"
+ context_service "code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/forms"
_ "code.gitea.io/gitea/routers/api/v1/swagger" // for swagger generation
@@ -156,6 +157,7 @@ func repoAssignment() func(ctx *context.APIContext) {
}
}
ctx.Repo.Owner = owner
+ ctx.ContextUser = owner
// Get repository.
repo, err := repo_model.GetRepositoryByName(owner.ID, repoName)
@@ -441,6 +443,7 @@ func orgAssignment(args ...bool) func(ctx *context.APIContext) {
}
return
}
+ ctx.ContextUser = ctx.Org.Organization.AsUser()
}
if assignTeam {
@@ -636,7 +639,7 @@ func Routes(sessioner func(http.Handler) http.Handler) *web.Route {
Post(bind(api.CreateAccessTokenOption{}), user.CreateAccessToken)
m.Combo("/{id}").Delete(user.DeleteAccessToken)
}, reqBasicOrRevProxyAuth())
- })
+ }, context_service.UserAssignmentAPI())
})
m.Group("/users", func() {
@@ -653,7 +656,7 @@ func Routes(sessioner func(http.Handler) http.Handler) *web.Route {
m.Get("/starred", user.GetStarredRepos)
m.Get("/subscriptions", user.GetWatchedRepos)
- })
+ }, context_service.UserAssignmentAPI())
}, reqToken())
m.Group("/user", func() {
@@ -669,7 +672,11 @@ func Routes(sessioner func(http.Handler) http.Handler) *web.Route {
m.Get("/followers", user.ListMyFollowers)
m.Group("/following", func() {
m.Get("", user.ListMyFollowing)
- m.Combo("/{username}").Get(user.CheckMyFollowing).Put(user.Follow).Delete(user.Unfollow)
+ m.Group("/{username}", func() {
+ m.Get("", user.CheckMyFollowing)
+ m.Put("", user.Follow)
+ m.Delete("", user.Unfollow)
+ }, context_service.UserAssignmentAPI())
})
m.Group("/keys", func() {
@@ -1005,7 +1012,7 @@ func Routes(sessioner func(http.Handler) http.Handler) *web.Route {
m.Group("/users/{username}/orgs", func() {
m.Get("", org.ListUserOrgs)
m.Get("/{org}/permissions", reqToken(), org.GetUserOrgsPermissions)
- })
+ }, context_service.UserAssignmentAPI())
m.Post("/orgs", reqToken(), bind(api.CreateOrgOption{}), org.Create)
m.Get("/orgs", org.GetAll)
m.Group("/orgs/{org}", func() {
@@ -1083,7 +1090,7 @@ func Routes(sessioner func(http.Handler) http.Handler) *web.Route {
m.Get("/orgs", org.ListUserOrgs)
m.Post("/orgs", bind(api.CreateOrgOption{}), admin.CreateOrg)
m.Post("/repos", bind(api.CreateRepoOption{}), admin.CreateRepo)
- })
+ }, context_service.UserAssignmentAPI())
})
m.Group("/unadopted", func() {
m.Get("", admin.ListUnadoptedRepositories)
diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go
index 63cc0e9d39..fcc98f4b78 100644
--- a/routers/api/v1/org/org.go
+++ b/routers/api/v1/org/org.go
@@ -99,11 +99,7 @@ func ListUserOrgs(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/OrganizationList"
- u := user.GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
- listUserOrgs(ctx, u)
+ listUserOrgs(ctx, ctx.ContextUser)
}
// GetUserOrgsPermissions get user permissions in organization
@@ -132,11 +128,6 @@ func GetUserOrgsPermissions(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- var u *user_model.User
- if u = user.GetUserByParams(ctx); u == nil {
- return
- }
-
var o *user_model.User
if o = user.GetUserByParamsName(ctx, ":org"); o == nil {
return
@@ -144,13 +135,13 @@ func GetUserOrgsPermissions(ctx *context.APIContext) {
op := api.OrganizationPermissions{}
- if !models.HasOrgOrUserVisible(o, u) {
+ if !models.HasOrgOrUserVisible(o, ctx.ContextUser) {
ctx.NotFound("HasOrgOrUserVisible", nil)
return
}
org := models.OrgFromUser(o)
- authorizeLevel, err := org.GetOrgUserMaxAuthorizeLevel(u.ID)
+ authorizeLevel, err := org.GetOrgUserMaxAuthorizeLevel(ctx.ContextUser.ID)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetOrgUserAuthorizeLevel", err)
return
@@ -169,7 +160,7 @@ func GetUserOrgsPermissions(ctx *context.APIContext) {
op.IsOwner = true
}
- op.CanCreateRepository, err = org.CanCreateOrgRepo(u.ID)
+ op.CanCreateRepository, err = org.CanCreateOrgRepo(ctx.ContextUser.ID)
if err != nil {
ctx.Error(http.StatusInternalServerError, "CanCreateOrgRepo", err)
return
diff --git a/routers/api/v1/user/follower.go b/routers/api/v1/user/follower.go
index 063f68519c..3c81b27f8d 100644
--- a/routers/api/v1/user/follower.go
+++ b/routers/api/v1/user/follower.go
@@ -82,11 +82,7 @@ func ListFollowers(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/UserList"
- u := GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
- listUserFollowers(ctx, u)
+ listUserFollowers(ctx, ctx.ContextUser)
}
func listUserFollowing(ctx *context.APIContext, u *user_model.User) {
@@ -148,11 +144,7 @@ func ListFollowing(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/UserList"
- u := GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
- listUserFollowing(ctx, u)
+ listUserFollowing(ctx, ctx.ContextUser)
}
func checkUserFollowing(ctx *context.APIContext, u *user_model.User, followID int64) {
@@ -180,25 +172,21 @@ func CheckMyFollowing(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- target := GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
- checkUserFollowing(ctx, ctx.Doer, target.ID)
+ checkUserFollowing(ctx, ctx.Doer, ctx.ContextUser.ID)
}
// CheckFollowing check if one user is following another user
func CheckFollowing(ctx *context.APIContext) {
- // swagger:operation GET /users/{follower}/following/{followee} user userCheckFollowing
+ // swagger:operation GET /users/{username}/following/{target} user userCheckFollowing
// ---
// summary: Check if one user is following another user
// parameters:
- // - name: follower
+ // - name: username
// in: path
// description: username of following user
// type: string
// required: true
- // - name: followee
+ // - name: target
// in: path
// description: username of followed user
// type: string
@@ -209,15 +197,11 @@ func CheckFollowing(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- u := GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
target := GetUserByParamsName(ctx, ":target")
if ctx.Written() {
return
}
- checkUserFollowing(ctx, u, target.ID)
+ checkUserFollowing(ctx, ctx.ContextUser, target.ID)
}
// Follow follow a user
@@ -235,11 +219,7 @@ func Follow(ctx *context.APIContext) {
// "204":
// "$ref": "#/responses/empty"
- target := GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
- if err := user_model.FollowUser(ctx.Doer.ID, target.ID); err != nil {
+ if err := user_model.FollowUser(ctx.Doer.ID, ctx.ContextUser.ID); err != nil {
ctx.Error(http.StatusInternalServerError, "FollowUser", err)
return
}
@@ -261,11 +241,7 @@ func Unfollow(ctx *context.APIContext) {
// "204":
// "$ref": "#/responses/empty"
- target := GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
- if err := user_model.UnfollowUser(ctx.Doer.ID, target.ID); err != nil {
+ if err := user_model.UnfollowUser(ctx.Doer.ID, ctx.ContextUser.ID); err != nil {
ctx.Error(http.StatusInternalServerError, "UnfollowUser", err)
return
}
diff --git a/routers/api/v1/user/gpg_key.go b/routers/api/v1/user/gpg_key.go
index 83122355d0..b211a24a0e 100644
--- a/routers/api/v1/user/gpg_key.go
+++ b/routers/api/v1/user/gpg_key.go
@@ -64,11 +64,7 @@ func ListGPGKeys(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/GPGKeyList"
- user := GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
- listGPGKeys(ctx, user.ID, utils.GetListOptions(ctx))
+ listGPGKeys(ctx, ctx.ContextUser.ID, utils.GetListOptions(ctx))
}
// ListMyGPGKeys get the GPG key list of the authenticated user
diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go
index 67ffec723d..cc7ee739ce 100644
--- a/routers/api/v1/user/key.go
+++ b/routers/api/v1/user/key.go
@@ -151,11 +151,7 @@ func ListPublicKeys(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/PublicKeyList"
- user := GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
- listPublicKeys(ctx, user)
+ listPublicKeys(ctx, ctx.ContextUser)
}
// GetPublicKey get a public key
diff --git a/routers/api/v1/user/repo.go b/routers/api/v1/user/repo.go
index 683c300953..0231c8ccbc 100644
--- a/routers/api/v1/user/repo.go
+++ b/routers/api/v1/user/repo.go
@@ -78,12 +78,8 @@ func ListUserRepos(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/RepositoryList"
- user := GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
private := ctx.IsSigned
- listUserRepos(ctx, user, private)
+ listUserRepos(ctx, ctx.ContextUser, private)
}
// ListMyRepos - list the repositories you own or have access to.
diff --git a/routers/api/v1/user/star.go b/routers/api/v1/user/star.go
index 95d3785a82..83f97f8f01 100644
--- a/routers/api/v1/user/star.go
+++ b/routers/api/v1/user/star.go
@@ -62,15 +62,14 @@ func GetStarredRepos(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/RepositoryList"
- user := GetUserByParams(ctx)
- private := user.ID == ctx.Doer.ID
- repos, err := getStarredRepos(user, private, utils.GetListOptions(ctx))
+ private := ctx.ContextUser.ID == ctx.Doer.ID
+ repos, err := getStarredRepos(ctx.ContextUser, private, utils.GetListOptions(ctx))
if err != nil {
ctx.Error(http.StatusInternalServerError, "getStarredRepos", err)
return
}
- ctx.SetTotalCountHeader(int64(user.NumStars))
+ ctx.SetTotalCountHeader(int64(ctx.ContextUser.NumStars))
ctx.JSON(http.StatusOK, &repos)
}
diff --git a/routers/api/v1/user/user.go b/routers/api/v1/user/user.go
index 56e6ad8879..e9d871c5c1 100644
--- a/routers/api/v1/user/user.go
+++ b/routers/api/v1/user/user.go
@@ -98,18 +98,12 @@ func GetInfo(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- u := GetUserByParams(ctx)
-
- if ctx.Written() {
- return
- }
-
- if !models.IsUserVisibleToViewer(u, ctx.Doer) {
+ if !models.IsUserVisibleToViewer(ctx.ContextUser, ctx.Doer) {
// fake ErrUserNotExist error message to not leak information about existence
ctx.NotFound("GetUserByName", user_model.ErrUserNotExist{Name: ctx.Params(":username")})
return
}
- ctx.JSON(http.StatusOK, convert.ToUser(u, ctx.Doer))
+ ctx.JSON(http.StatusOK, convert.ToUser(ctx.ContextUser, ctx.Doer))
}
// GetAuthenticatedUser get current user's information
@@ -145,12 +139,7 @@ func GetUserHeatmapData(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- user := GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
-
- heatmap, err := models.GetUserHeatmapDataByUser(user, ctx.Doer)
+ heatmap, err := models.GetUserHeatmapDataByUser(ctx.ContextUser, ctx.Doer)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetUserHeatmapDataByUser", err)
return
diff --git a/routers/api/v1/user/watch.go b/routers/api/v1/user/watch.go
index 718a9282ed..22e76f5ebc 100644
--- a/routers/api/v1/user/watch.go
+++ b/routers/api/v1/user/watch.go
@@ -60,9 +60,8 @@ func GetWatchedRepos(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/RepositoryList"
- user := GetUserByParams(ctx)
- private := user.ID == ctx.Doer.ID
- repos, total, err := getWatchedRepos(user, private, utils.GetListOptions(ctx))
+ private := ctx.ContextUser.ID == ctx.Doer.ID
+ repos, total, err := getWatchedRepos(ctx.ContextUser, private, utils.GetListOptions(ctx))
if err != nil {
ctx.Error(http.StatusInternalServerError, "getWatchedRepos", err)
}
diff --git a/routers/web/feed/profile.go b/routers/web/feed/profile.go
index 32898c6ee7..61a39755f5 100644
--- a/routers/web/feed/profile.go
+++ b/routers/web/feed/profile.go
@@ -9,19 +9,28 @@ import (
"time"
"code.gitea.io/gitea/models"
- user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context"
"github.com/gorilla/feeds"
)
-// ShowUserFeed show user activity as RSS / Atom feed
-func ShowUserFeed(ctx *context.Context, ctxUser *user_model.User, formatType string) {
+// ShowUserFeedRSS show user activity as RSS feed
+func ShowUserFeedRSS(ctx *context.Context) {
+ showUserFeed(ctx, "rss")
+}
+
+// ShowUserFeedAtom show user activity as Atom feed
+func ShowUserFeedAtom(ctx *context.Context) {
+ showUserFeed(ctx, "atom")
+}
+
+// showUserFeed show user activity as RSS / Atom feed
+func showUserFeed(ctx *context.Context, formatType string) {
actions, err := models.GetFeeds(ctx, models.GetFeedsOptions{
- RequestedUser: ctxUser,
+ RequestedUser: ctx.ContextUser,
Actor: ctx.Doer,
IncludePrivate: false,
- OnlyPerformedBy: !ctxUser.IsOrganization(),
+ OnlyPerformedBy: !ctx.ContextUser.IsOrganization(),
IncludeDeleted: false,
Date: ctx.FormString("date"),
})
@@ -31,9 +40,9 @@ func ShowUserFeed(ctx *context.Context, ctxUser *user_model.User, formatType str
}
feed := &feeds.Feed{
- Title: ctx.Tr("home.feed_of", ctxUser.DisplayName()),
- Link: &feeds.Link{Href: ctxUser.HTMLURL()},
- Description: ctxUser.Description,
+ Title: ctx.Tr("home.feed_of", ctx.ContextUser.DisplayName()),
+ Link: &feeds.Link{Href: ctx.ContextUser.HTMLURL()},
+ Description: ctx.ContextUser.Description,
Created: time.Now(),
}
diff --git a/routers/web/repo/http.go b/routers/web/repo/http.go
index 0207cd7685..d149d4f89f 100644
--- a/routers/web/repo/http.go
+++ b/routers/web/repo/http.go
@@ -24,7 +24,6 @@ import (
"code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
@@ -110,19 +109,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) {
reponame = reponame[:len(reponame)-5]
}
- owner, err := user_model.GetUserByName(username)
- if err != nil {
- if user_model.IsErrUserNotExist(err) {
- if redirectUserID, err := user_model.LookupUserRedirect(username); err == nil {
- context.RedirectToUser(ctx, username, redirectUserID)
- } else {
- ctx.NotFound(fmt.Sprintf("User %s does not exist", username), nil)
- }
- } else {
- ctx.ServerError("GetUserByName", err)
- }
- return
- }
+ owner := ctx.ContextUser
if !owner.IsOrganization() && !owner.IsActive {
ctx.PlainText(http.StatusForbidden, "Repository cannot be accessed. You cannot push or open issues/pull-requests.")
return
diff --git a/routers/web/user/home.go b/routers/web/user/home.go
index d3810f887d..e0beb0cbee 100644
--- a/routers/web/user/home.go
+++ b/routers/web/user/home.go
@@ -756,8 +756,8 @@ func loadRepoByIDs(ctxUser *user_model.User, issueCountByRepo map[int64]int64, u
}
// ShowSSHKeys output all the ssh keys of user by uid
-func ShowSSHKeys(ctx *context.Context, uid int64) {
- keys, err := asymkey_model.ListPublicKeys(uid, db.ListOptions{})
+func ShowSSHKeys(ctx *context.Context) {
+ keys, err := asymkey_model.ListPublicKeys(ctx.ContextUser.ID, db.ListOptions{})
if err != nil {
ctx.ServerError("ListPublicKeys", err)
return
@@ -772,8 +772,8 @@ func ShowSSHKeys(ctx *context.Context, uid int64) {
}
// ShowGPGKeys output all the public GPG keys of user by uid
-func ShowGPGKeys(ctx *context.Context, uid int64) {
- keys, err := asymkey_model.ListGPGKeys(ctx, uid, db.ListOptions{})
+func ShowGPGKeys(ctx *context.Context) {
+ keys, err := asymkey_model.ListGPGKeys(ctx, ctx.ContextUser.ID, db.ListOptions{})
if err != nil {
ctx.ServerError("ListGPGKeys", err)
return
diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go
index ca8011a6cf..db2660af61 100644
--- a/routers/web/user/profile.go
+++ b/routers/web/user/profile.go
@@ -8,7 +8,6 @@ package user
import (
"fmt"
"net/http"
- "path"
"strings"
"code.gitea.io/gitea/models"
@@ -24,121 +23,51 @@ import (
"code.gitea.io/gitea/routers/web/org"
)
-// GetUserByName get user by name
-func GetUserByName(ctx *context.Context, name string) *user_model.User {
- user, err := user_model.GetUserByName(name)
- if err != nil {
- if user_model.IsErrUserNotExist(err) {
- if redirectUserID, err := user_model.LookupUserRedirect(name); err == nil {
- context.RedirectToUser(ctx, name, redirectUserID)
- } else {
- ctx.NotFound("GetUserByName", err)
- }
- } else {
- ctx.ServerError("GetUserByName", err)
- }
- return nil
- }
- return user
-}
-
-// GetUserByParams returns user whose name is presented in URL paramenter.
-func GetUserByParams(ctx *context.Context) *user_model.User {
- return GetUserByName(ctx, ctx.Params(":username"))
-}
-
// Profile render user's profile page
func Profile(ctx *context.Context) {
- uname := ctx.Params(":username")
-
- // Special handle for FireFox requests favicon.ico.
- if uname == "favicon.ico" {
- ctx.ServeFile(path.Join(setting.StaticRootPath, "public/img/favicon.png"))
+ if strings.Contains(ctx.Req.Header.Get("Accept"), "application/rss+xml") {
+ feed.ShowUserFeedRSS(ctx)
return
}
-
- if strings.HasSuffix(uname, ".png") {
- ctx.Error(http.StatusNotFound)
- return
- }
-
- isShowKeys := false
- if strings.HasSuffix(uname, ".keys") {
- isShowKeys = true
- uname = strings.TrimSuffix(uname, ".keys")
- }
-
- isShowGPG := false
- if strings.HasSuffix(uname, ".gpg") {
- isShowGPG = true
- uname = strings.TrimSuffix(uname, ".gpg")
- }
-
- isShowFeed, uname, showFeedType := feed.GetFeedType(uname, ctx.Req)
-
- ctxUser := GetUserByName(ctx, uname)
- if ctx.Written() {
+ if strings.Contains(ctx.Req.Header.Get("Accept"), "application/atom+xml") {
+ feed.ShowUserFeedAtom(ctx)
return
}
- if ctxUser.IsOrganization() {
- // Show Org RSS feed
- if isShowFeed {
- feed.ShowUserFeed(ctx, ctxUser, showFeedType)
- return
- }
-
+ if ctx.ContextUser.IsOrganization() {
org.Home(ctx)
return
}
// check view permissions
- if !models.IsUserVisibleToViewer(ctxUser, ctx.Doer) {
- ctx.NotFound("user", fmt.Errorf(uname))
- return
- }
-
- // Show SSH keys.
- if isShowKeys {
- ShowSSHKeys(ctx, ctxUser.ID)
- return
- }
-
- // Show GPG keys.
- if isShowGPG {
- ShowGPGKeys(ctx, ctxUser.ID)
- return
- }
-
- // Show User RSS feed
- if isShowFeed {
- feed.ShowUserFeed(ctx, ctxUser, showFeedType)
+ if !models.IsUserVisibleToViewer(ctx.ContextUser, ctx.Doer) {
+ ctx.NotFound("user", fmt.Errorf(ctx.ContextUser.Name))
return
}
// advertise feed via meta tag
- ctx.Data["FeedURL"] = ctxUser.HTMLURL()
+ ctx.Data["FeedURL"] = ctx.ContextUser.HTMLURL()
// Show OpenID URIs
- openIDs, err := user_model.GetUserOpenIDs(ctxUser.ID)
+ openIDs, err := user_model.GetUserOpenIDs(ctx.ContextUser.ID)
if err != nil {
ctx.ServerError("GetUserOpenIDs", err)
return
}
var isFollowing bool
- if ctx.Doer != nil && ctxUser != nil {
- isFollowing = user_model.IsFollowing(ctx.Doer.ID, ctxUser.ID)
+ if ctx.Doer != nil {
+ isFollowing = user_model.IsFollowing(ctx.Doer.ID, ctx.ContextUser.ID)
}
- ctx.Data["Title"] = ctxUser.DisplayName()
+ ctx.Data["Title"] = ctx.ContextUser.DisplayName()
ctx.Data["PageIsUserProfile"] = true
- ctx.Data["Owner"] = ctxUser
+ ctx.Data["Owner"] = ctx.ContextUser
ctx.Data["OpenIDs"] = openIDs
ctx.Data["IsFollowing"] = isFollowing
if setting.Service.EnableUserHeatmap {
- data, err := models.GetUserHeatmapDataByUser(ctxUser, ctx.Doer)
+ data, err := models.GetUserHeatmapDataByUser(ctx.ContextUser, ctx.Doer)
if err != nil {
ctx.ServerError("GetUserHeatmapDataByUser", err)
return
@@ -146,13 +75,13 @@ func Profile(ctx *context.Context) {
ctx.Data["HeatmapData"] = data
}
- if len(ctxUser.Description) != 0 {
+ if len(ctx.ContextUser.Description) != 0 {
content, err := markdown.RenderString(&markup.RenderContext{
URLPrefix: ctx.Repo.RepoLink,
Metas: map[string]string{"mode": "document"},
GitRepo: ctx.Repo.GitRepo,
Ctx: ctx,
- }, ctxUser.Description)
+ }, ctx.ContextUser.Description)
if err != nil {
ctx.ServerError("RenderString", err)
return
@@ -160,10 +89,10 @@ func Profile(ctx *context.Context) {
ctx.Data["RenderedDescription"] = content
}
- showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctxUser.ID)
+ showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID)
orgs, err := models.FindOrgs(models.FindOrgOptions{
- UserID: ctxUser.ID,
+ UserID: ctx.ContextUser.ID,
IncludePrivate: showPrivate,
})
if err != nil {
@@ -226,7 +155,7 @@ func Profile(ctx *context.Context) {
switch tab {
case "followers":
- items, err := user_model.GetUserFollowers(ctxUser, db.ListOptions{
+ items, err := user_model.GetUserFollowers(ctx.ContextUser, db.ListOptions{
PageSize: setting.UI.User.RepoPagingNum,
Page: page,
})
@@ -236,9 +165,9 @@ func Profile(ctx *context.Context) {
}
ctx.Data["Cards"] = items
- total = ctxUser.NumFollowers
+ total = ctx.ContextUser.NumFollowers
case "following":
- items, err := user_model.GetUserFollowing(ctxUser, db.ListOptions{
+ items, err := user_model.GetUserFollowing(ctx.ContextUser, db.ListOptions{
PageSize: setting.UI.User.RepoPagingNum,
Page: page,
})
@@ -248,10 +177,10 @@ func Profile(ctx *context.Context) {
}
ctx.Data["Cards"] = items
- total = ctxUser.NumFollowing
+ total = ctx.ContextUser.NumFollowing
case "activity":
ctx.Data["Feeds"], err = models.GetFeeds(ctx, models.GetFeedsOptions{
- RequestedUser: ctxUser,
+ RequestedUser: ctx.ContextUser,
Actor: ctx.Doer,
IncludePrivate: showPrivate,
OnlyPerformedBy: true,
@@ -273,7 +202,7 @@ func Profile(ctx *context.Context) {
Keyword: keyword,
OrderBy: orderBy,
Private: ctx.IsSigned,
- StarredByID: ctxUser.ID,
+ StarredByID: ctx.ContextUser.ID,
Collaborate: util.OptionalBoolFalse,
TopicOnly: topicOnly,
Language: language,
@@ -305,7 +234,7 @@ func Profile(ctx *context.Context) {
Keyword: keyword,
OrderBy: orderBy,
Private: ctx.IsSigned,
- WatchedByID: ctxUser.ID,
+ WatchedByID: ctx.ContextUser.ID,
Collaborate: util.OptionalBoolFalse,
TopicOnly: topicOnly,
Language: language,
@@ -325,7 +254,7 @@ func Profile(ctx *context.Context) {
},
Actor: ctx.Doer,
Keyword: keyword,
- OwnerID: ctxUser.ID,
+ OwnerID: ctx.ContextUser.ID,
OrderBy: orderBy,
Private: ctx.IsSigned,
Collaborate: util.OptionalBoolFalse,
@@ -350,24 +279,19 @@ func Profile(ctx *context.Context) {
}
ctx.Data["Page"] = pager
- ctx.Data["ShowUserEmail"] = len(ctxUser.Email) > 0 && ctx.IsSigned && (!ctxUser.KeepEmailPrivate || ctxUser.ID == ctx.Doer.ID)
+ ctx.Data["ShowUserEmail"] = len(ctx.ContextUser.Email) > 0 && ctx.IsSigned && (!ctx.ContextUser.KeepEmailPrivate || ctx.ContextUser.ID == ctx.Doer.ID)
ctx.HTML(http.StatusOK, tplProfile)
}
// Action response for follow/unfollow user request
func Action(ctx *context.Context) {
- u := GetUserByParams(ctx)
- if ctx.Written() {
- return
- }
-
var err error
switch ctx.FormString("action") {
case "follow":
- err = user_model.FollowUser(ctx.Doer.ID, u.ID)
+ err = user_model.FollowUser(ctx.Doer.ID, ctx.ContextUser.ID)
case "unfollow":
- err = user_model.UnfollowUser(ctx.Doer.ID, u.ID)
+ err = user_model.UnfollowUser(ctx.Doer.ID, ctx.ContextUser.ID)
}
if err != nil {
@@ -375,5 +299,5 @@ func Action(ctx *context.Context) {
return
}
// FIXME: We should check this URL and make sure that it's a valid Gitea URL
- ctx.RedirectToFirst(ctx.FormString("redirect_to"), u.HomeLink())
+ ctx.RedirectToFirst(ctx.FormString("redirect_to"), ctx.ContextUser.HomeLink())
}
diff --git a/routers/web/web.go b/routers/web/web.go
index b40a43058d..f4cabaab6e 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -29,12 +29,14 @@ import (
"code.gitea.io/gitea/routers/web/dev"
"code.gitea.io/gitea/routers/web/events"
"code.gitea.io/gitea/routers/web/explore"
+ "code.gitea.io/gitea/routers/web/feed"
"code.gitea.io/gitea/routers/web/org"
"code.gitea.io/gitea/routers/web/repo"
"code.gitea.io/gitea/routers/web/user"
user_setting "code.gitea.io/gitea/routers/web/user/setting"
"code.gitea.io/gitea/routers/web/user/setting/security"
auth_service "code.gitea.io/gitea/services/auth"
+ context_service "code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/forms"
"code.gitea.io/gitea/services/lfs"
"code.gitea.io/gitea/services/mailer"
@@ -496,11 +498,21 @@ func RegisterRoutes(m *web.Route) {
// ***** END: Admin *****
m.Group("", func() {
- m.Get("/{username}", user.Profile)
+ m.Get("/favicon.ico", func(ctx *context.Context) {
+ ctx.ServeFile(path.Join(setting.StaticRootPath, "public/img/favicon.png"))
+ })
+ m.Group("/{username}", func() {
+ m.Get(".png", func(ctx *context.Context) { ctx.Error(http.StatusNotFound) })
+ m.Get(".keys", user.ShowSSHKeys)
+ m.Get(".gpg", user.ShowGPGKeys)
+ m.Get(".rss", feed.ShowUserFeedRSS)
+ m.Get(".atom", feed.ShowUserFeedAtom)
+ m.Get("", user.Profile)
+ }, context_service.UserAssignmentWeb())
m.Get("/attachments/{uuid}", repo.GetAttachment)
}, ignSignIn)
- m.Post("/{username}", reqSignIn, user.Action)
+ m.Post("/{username}", reqSignIn, context_service.UserAssignmentWeb(), user.Action)
if !setting.IsProd {
m.Get("/template/*", dev.TemplatePreview)
@@ -1107,7 +1119,7 @@ func RegisterRoutes(m *web.Route) {
m.GetOptions("/objects/{head:[0-9a-f]{2}}/{hash:[0-9a-f]{38}}", repo.GetLooseObject)
m.GetOptions("/objects/pack/pack-{file:[0-9a-f]{40}}.pack", repo.GetPackFile)
m.GetOptions("/objects/pack/pack-{file:[0-9a-f]{40}}.idx", repo.GetIdxFile)
- }, ignSignInAndCsrf)
+ }, ignSignInAndCsrf, context_service.UserAssignmentWeb())
})
})
// ***** END: Repository *****
diff --git a/services/context/user.go b/services/context/user.go
new file mode 100644
index 0000000000..c5efd43782
--- /dev/null
+++ b/services/context/user.go
@@ -0,0 +1,62 @@
+// Copyright 2022 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 context
+
+import (
+ "fmt"
+ "net/http"
+ "strings"
+
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/context"
+)
+
+// UserAssignmentWeb returns a middleware to handle context-user assignment for web routes
+func UserAssignmentWeb() func(ctx *context.Context) {
+ return func(ctx *context.Context) {
+ userAssignment(ctx, func(status int, title string, obj interface{}) {
+ err, ok := obj.(error)
+ if !ok {
+ err = fmt.Errorf("%s", obj)
+ }
+ if status == http.StatusNotFound {
+ ctx.NotFound(title, err)
+ } else {
+ ctx.ServerError(title, err)
+ }
+ })
+ }
+}
+
+// UserAssignmentAPI returns a middleware to handle context-user assignment for api routes
+func UserAssignmentAPI() func(ctx *context.APIContext) {
+ return func(ctx *context.APIContext) {
+ userAssignment(ctx.Context, ctx.Error)
+ }
+}
+
+func userAssignment(ctx *context.Context, errCb func(int, string, interface{})) {
+ username := ctx.Params(":username")
+
+ if ctx.IsSigned && ctx.Doer.LowerName == strings.ToLower(username) {
+ ctx.ContextUser = ctx.Doer
+ } else {
+ var err error
+ ctx.ContextUser, err = user_model.GetUserByName(username)
+ if err != nil {
+ if user_model.IsErrUserNotExist(err) {
+ if redirectUserID, err := user_model.LookupUserRedirect(username); err == nil {
+ context.RedirectToUser(ctx, username, redirectUserID)
+ } else if user_model.IsErrUserRedirectNotExist(err) {
+ errCb(http.StatusNotFound, "GetUserByName", err)
+ } else {
+ errCb(http.StatusInternalServerError, "LookupUserRedirect", err)
+ }
+ } else {
+ errCb(http.StatusInternalServerError, "GetUserByName", err)
+ }
+ }
+ }
+}
diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl
index 4f2e7dbb1a..1aec9ec06f 100644
--- a/templates/swagger/v1_json.tmpl
+++ b/templates/swagger/v1_json.tmpl
@@ -12087,39 +12087,6 @@
}
}
},
- "/users/{follower}/following/{followee}": {
- "get": {
- "tags": [
- "user"
- ],
- "summary": "Check if one user is following another user",
- "operationId": "userCheckFollowing",
- "parameters": [
- {
- "type": "string",
- "description": "username of following user",
- "name": "follower",
- "in": "path",
- "required": true
- },
- {
- "type": "string",
- "description": "username of followed user",
- "name": "followee",
- "in": "path",
- "required": true
- }
- ],
- "responses": {
- "204": {
- "$ref": "#/responses/empty"
- },
- "404": {
- "$ref": "#/responses/notFound"
- }
- }
- }
- },
"/users/{username}": {
"get": {
"produces": [
@@ -12225,6 +12192,39 @@
}
}
},
+ "/users/{username}/following/{target}": {
+ "get": {
+ "tags": [
+ "user"
+ ],
+ "summary": "Check if one user is following another user",
+ "operationId": "userCheckFollowing",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "username of following user",
+ "name": "username",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "username of followed user",
+ "name": "target",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "204": {
+ "$ref": "#/responses/empty"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ }
+ }
+ }
+ },
"/users/{username}/gpg_keys": {
"get": {
"produces": [