Delete a user's public key via admin api (closes #3014) (#3059)

* Delete a user's public key via admin api

* Test admin ssh endpoint for creating a new ssh key

* Adapt public ssh key test to also test the delete operation

* Test that deleting a missing key will result in a 404

* Test that a normal user can't delete another user's ssh key

* Make DeletePublicKey return err

* Update swagger doc
This commit is contained in:
Vlad Temian 2017-12-06 12:27:10 +02:00 committed by Lauris BH
parent c7fb6e3087
commit 469ab99e9a
6 changed files with 324 additions and 11 deletions

View File

@ -0,0 +1,73 @@
// Copyright 2017 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 integrations
import (
"fmt"
"net/http"
"testing"
"code.gitea.io/gitea/models"
api "code.gitea.io/sdk/gitea"
)
func TestAPIAdminCreateAndDeleteSSHKey(t *testing.T) {
prepareTestEnv(t)
// user1 is an admin user
session := loginUser(t, "user1")
keyOwner := models.AssertExistsAndLoadBean(t, &models.User{Name: "user2"}).(*models.User)
urlStr := fmt.Sprintf("/api/v1/admin/users/%s/keys", keyOwner.Name)
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAu7tvIvX6ZHrRXuZNfkR3XLHSsuCK9Zn3X58lxBcQzuo5xZgB6vRwwm/QtJuF+zZPtY5hsQILBLmF+BZ5WpKZp1jBeSjH2G7lxet9kbcH+kIVj0tPFEoyKI9wvWqIwC4prx/WVk2wLTJjzBAhyNxfEq7C9CeiX9pQEbEqJfkKCQ== nocomment\n",
"title": "test-key",
})
resp := session.MakeRequest(t, req, http.StatusCreated)
var newPublicKey api.PublicKey
DecodeJSON(t, resp, &newPublicKey)
models.AssertExistsAndLoadBean(t, &models.PublicKey{
ID: newPublicKey.ID,
Name: newPublicKey.Title,
Content: newPublicKey.Key,
Fingerprint: newPublicKey.Fingerprint,
OwnerID: keyOwner.ID,
})
req = NewRequestf(t, "DELETE", "/api/v1/admin/users/%s/keys/%d",
keyOwner.Name, newPublicKey.ID)
session.MakeRequest(t, req, http.StatusNoContent)
models.AssertNotExistsBean(t, &models.PublicKey{ID: newPublicKey.ID})
}
func TestAPIAdminDeleteMissingSSHKey(t *testing.T) {
prepareTestEnv(t)
// user1 is an admin user
session := loginUser(t, "user1")
req := NewRequestf(t, "DELETE", "/api/v1/admin/users/user1/keys/%d", models.NonexistentID)
session.MakeRequest(t, req, http.StatusNotFound)
}
func TestAPIAdminDeleteUnauthorizedKey(t *testing.T) {
prepareTestEnv(t)
adminUsername := "user1"
normalUsername := "user2"
session := loginUser(t, adminUsername)
urlStr := fmt.Sprintf("/api/v1/admin/users/%s/keys", adminUsername)
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAu7tvIvX6ZHrRXuZNfkR3XLHSsuCK9Zn3X58lxBcQzuo5xZgB6vRwwm/QtJuF+zZPtY5hsQILBLmF+BZ5WpKZp1jBeSjH2G7lxet9kbcH+kIVj0tPFEoyKI9wvWqIwC4prx/WVk2wLTJjzBAhyNxfEq7C9CeiX9pQEbEqJfkKCQ== nocomment\n",
"title": "test-key",
})
resp := session.MakeRequest(t, req, http.StatusCreated)
var newPublicKey api.PublicKey
DecodeJSON(t, resp, &newPublicKey)
session = loginUser(t, normalUsername)
req = NewRequestf(t, "DELETE", "/api/v1/admin/users/%s/keys/%d",
adminUsername, newPublicKey.ID)
session.MakeRequest(t, req, http.StatusForbidden)
}

View File

@ -506,10 +506,7 @@ func deletePublicKeys(e *xorm.Session, keyIDs ...int64) error {
func DeletePublicKey(doer *User, id int64) (err error) {
key, err := GetPublicKeyByID(id)
if err != nil {
if IsErrKeyNotExist(err) {
return nil
}
return fmt.Errorf("GetPublicKeyByID: %v", err)
return err
}
// Check if user has access to delete this key.

201
public/swagger.v1.json vendored
View File

@ -36,6 +36,7 @@
],
"summary": "Create a user",
"operationId": "adminCreateUser",
"security": null,
"parameters": [
{
"name": "body",
@ -68,6 +69,7 @@
],
"summary": "Delete a user",
"operationId": "adminDeleteUser",
"security": null,
"parameters": [
{
"type": "string",
@ -101,6 +103,7 @@
],
"summary": "Edit an existing user",
"operationId": "adminEditUser",
"security": null,
"parameters": [
{
"type": "string",
@ -143,6 +146,7 @@
],
"summary": "Add a public key on behalf of a user",
"operationId": "adminCreatePublicKey",
"security": null,
"parameters": [
{
"type": "string",
@ -165,6 +169,46 @@
}
}
},
"/admin/users/{username}/keys/{id}": {
"delete": {
"produces": [
"application/json"
],
"tags": [
"admin"
],
"summary": "Delete a user's public key",
"operationId": "adminDeleteUserPublicKey",
"security": null,
"parameters": [
{
"type": "string",
"description": "username of user",
"name": "username",
"in": "path",
"required": true
},
{
"type": "integer",
"description": "id of the key to delete",
"name": "id",
"in": "path",
"required": true
}
],
"responses": {
"204": {
"$ref": "#/responses/empty"
},
"403": {
"$ref": "#/responses/forbidden"
},
"404": {
"$ref": "#/responses/notFound"
}
}
}
},
"/admin/users/{username}/orgs": {
"post": {
"consumes": [
@ -178,6 +222,7 @@
],
"summary": "Create an organization",
"operationId": "adminCreateOrg",
"security": null,
"parameters": [
{
"type": "string",
@ -213,6 +258,7 @@
],
"summary": "Create a repository on behalf a user",
"operationId": "adminCreateRepo",
"security": null,
"parameters": [
{
"type": "string",
@ -248,6 +294,7 @@
],
"summary": "Render a markdown document as HTML",
"operationId": "renderMarkdown",
"security": null,
"parameters": [
{
"name": "body",
@ -280,6 +327,7 @@
],
"summary": "Render raw markdown as HTML",
"operationId": "renderMarkdownRaw",
"security": null,
"parameters": [
{
"type": "string",
@ -310,6 +358,7 @@
],
"summary": "Create a repository in an organization",
"operationId": "createOrgRepo",
"security": null,
"parameters": [
{
"type": "string",
@ -349,6 +398,7 @@
],
"summary": "Get an organization",
"operationId": "orgGet",
"security": null,
"parameters": [
{
"type": "string",
@ -376,6 +426,7 @@
],
"summary": "Edit an organization",
"operationId": "orgEdit",
"security": null,
"parameters": [
{
"type": "string",
@ -409,6 +460,7 @@
],
"summary": "List an organization's webhooks",
"operationId": "orgListHooks",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/HookList"
@ -429,6 +481,7 @@
],
"summary": "Create a hook",
"operationId": "orgCreateHook",
"security": null,
"responses": {
"201": {
"$ref": "#/responses/Hook"
@ -446,6 +499,7 @@
],
"summary": "Get a hook",
"operationId": "orgGetHook",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/Hook"
@ -461,6 +515,7 @@
],
"summary": "Delete a hook",
"operationId": "orgDeleteHook",
"security": null,
"responses": {
"204": {
"$ref": "#/responses/empty"
@ -479,6 +534,7 @@
],
"summary": "Update a hook",
"operationId": "orgEditHook",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/Hook"
@ -496,6 +552,7 @@
],
"summary": "List an organization's members",
"operationId": "orgListMembers",
"security": null,
"parameters": [
{
"type": "string",
@ -519,6 +576,7 @@
],
"summary": "Check if a user is a member of an organization",
"operationId": "orgIsMember",
"security": null,
"parameters": [
{
"type": "string",
@ -559,6 +617,7 @@
],
"summary": "Remove a member from an organization",
"operationId": "orgDeleteMember",
"security": null,
"parameters": [
{
"type": "string",
@ -595,6 +654,7 @@
],
"summary": "List an organization's public members",
"operationId": "orgListPublicMembers",
"security": null,
"parameters": [
{
"type": "string",
@ -618,6 +678,7 @@
],
"summary": "Check if a user is a public member of an organization",
"operationId": "orgIsPublicMember",
"security": null,
"parameters": [
{
"type": "string",
@ -658,6 +719,7 @@
],
"summary": "Publicize a user's membership",
"operationId": "orgPublicizeMember",
"security": null,
"parameters": [
{
"type": "string",
@ -692,6 +754,7 @@
],
"summary": "Conceal a user's membership",
"operationId": "orgConcealMember",
"security": null,
"parameters": [
{
"type": "string",
@ -725,6 +788,7 @@
],
"summary": "List an organization's repos",
"operationId": "orgListRepos",
"security": null,
"parameters": [
{
"type": "string",
@ -751,6 +815,7 @@
],
"summary": "List an organization's teams",
"operationId": "orgListTeams",
"security": null,
"parameters": [
{
"type": "string",
@ -778,6 +843,7 @@
],
"summary": "Create a team",
"operationId": "orgCreateTeam",
"security": null,
"parameters": [
{
"type": "string",
@ -814,6 +880,7 @@
],
"summary": "Migrate a remote git repository",
"operationId": "repoMigrate",
"security": null,
"parameters": [
{
"name": "body",
@ -840,6 +907,7 @@
],
"summary": "Search for repositories",
"operationId": "repoSearch",
"security": null,
"parameters": [
{
"type": "string",
@ -898,6 +966,7 @@
],
"summary": "Get a repository",
"operationId": "repoGet",
"security": null,
"parameters": [
{
"type": "string",
@ -929,6 +998,7 @@
],
"summary": "Delete a repository",
"operationId": "repoDelete",
"security": null,
"parameters": [
{
"type": "string",
@ -965,6 +1035,7 @@
],
"summary": "Get an archive of a repository",
"operationId": "repoGetArchive",
"security": null,
"parameters": [
{
"type": "string",
@ -1003,6 +1074,7 @@
],
"summary": "List a repository's branches",
"operationId": "repoListBranches",
"security": null,
"parameters": [
{
"type": "string",
@ -1036,6 +1108,7 @@
],
"summary": "List a repository's branches",
"operationId": "repoGetBranch",
"security": null,
"parameters": [
{
"type": "string",
@ -1076,6 +1149,7 @@
],
"summary": "List a repository's collaborators",
"operationId": "repoListCollaborators",
"security": null,
"parameters": [
{
"type": "string",
@ -1109,6 +1183,7 @@
],
"summary": "Check if a user is a collaborator of a repository",
"operationId": "repoCheckCollaborator",
"security": null,
"parameters": [
{
"type": "string",
@ -1150,6 +1225,7 @@
],
"summary": "Add a collaborator to a repository",
"operationId": "repoAddCollaborator",
"security": null,
"parameters": [
{
"type": "string",
@ -1195,6 +1271,7 @@
],
"summary": "Delete a collaborator from a repository",
"operationId": "repoDeleteCollaborator",
"security": null,
"parameters": [
{
"type": "string",
@ -1235,6 +1312,7 @@
],
"summary": "Get a commit's combined status, by branch/tag/commit reference",
"operationId": "repoGetCombinedStatusByRef",
"security": null,
"parameters": [
{
"type": "string",
@ -1275,6 +1353,7 @@
],
"summary": "Get the EditorConfig definitions of a file in a repository",
"operationId": "repoGetEditorConfig",
"security": null,
"parameters": [
{
"type": "string",
@ -1313,6 +1392,7 @@
],
"summary": "List a repository's forks",
"operationId": "listForks",
"security": null,
"parameters": [
{
"type": "string",
@ -1344,6 +1424,7 @@
],
"summary": "Fork a repository",
"operationId": "createFork",
"security": null,
"parameters": [
{
"type": "string",
@ -1384,6 +1465,7 @@
],
"summary": "List the hooks in a repository",
"operationId": "repoListHooks",
"security": null,
"parameters": [
{
"type": "string",
@ -1418,6 +1500,7 @@
],
"summary": "Create a hook",
"operationId": "repoCreateHook",
"security": null,
"parameters": [
{
"type": "string",
@ -1458,6 +1541,7 @@
],
"summary": "Get a hook",
"operationId": "repoGetHook",
"security": null,
"parameters": [
{
"type": "string",
@ -1496,6 +1580,7 @@
],
"summary": "Edit a hook in a repository",
"operationId": "repoEditHook",
"security": null,
"parameters": [
{
"type": "string",
@ -1536,6 +1621,7 @@
],
"summary": "List all comments on an issue",
"operationId": "issueGetComments",
"security": null,
"parameters": [
{
"type": "string",
@ -1585,6 +1671,7 @@
],
"summary": "Replace an issue's labels",
"operationId": "issueReplaceLabels",
"security": null,
"parameters": [
{
"type": "string",
@ -1633,6 +1720,7 @@
],
"summary": "Add a label to an issue",
"operationId": "issueAddLabel",
"security": null,
"parameters": [
{
"type": "string",
@ -1678,6 +1766,7 @@
],
"summary": "Remove all labels from an issue",
"operationId": "issueClearLabels",
"security": null,
"parameters": [
{
"type": "string",
@ -1718,6 +1807,7 @@
],
"summary": "Remove a label from an issue",
"operationId": "issueRemoveLabel",
"security": null,
"parameters": [
{
"type": "string",
@ -1765,6 +1855,7 @@
],
"summary": "List a repository's issues",
"operationId": "issueListIssues",
"security": null,
"parameters": [
{
"type": "string",
@ -1811,6 +1902,7 @@
],
"summary": "Create an issue",
"operationId": "issueCreateIssue",
"security": null,
"parameters": [
{
"type": "string",
@ -1851,6 +1943,7 @@
],
"summary": "List all comments in a repository",
"operationId": "issueGetRepoComments",
"security": null,
"parameters": [
{
"type": "string",
@ -1887,6 +1980,7 @@
],
"summary": "Delete a comment",
"operationId": "issueDeleteComment",
"security": null,
"parameters": [
{
"type": "string",
@ -1928,6 +2022,7 @@
],
"summary": "Edit a comment",
"operationId": "issueEditComment",
"security": null,
"parameters": [
{
"type": "string",
@ -1975,6 +2070,7 @@
],
"summary": "Get an issue by id",
"operationId": "issueGetIssue",
"security": null,
"parameters": [
{
"type": "string",
@ -2016,6 +2112,7 @@
],
"summary": "Edit an issue",
"operationId": "issueEditIssue",
"security": null,
"parameters": [
{
"type": "string",
@ -2066,6 +2163,7 @@
],
"summary": "Add a comment to an issue",
"operationId": "issueCreateComment",
"security": null,
"parameters": [
{
"type": "string",
@ -2111,6 +2209,7 @@
"summary": "Delete a comment",
"operationId": "issueDeleteCommentDeprecated",
"deprecated": true,
"security": null,
"parameters": [
{
"type": "string",
@ -2160,6 +2259,7 @@
"summary": "Edit a comment",
"operationId": "issueEditCommentDeprecated",
"deprecated": true,
"security": null,
"parameters": [
{
"type": "string",
@ -2214,6 +2314,7 @@
],
"summary": "Get an issue's labels",
"operationId": "issueGetLabels",
"security": null,
"parameters": [
{
"type": "string",
@ -2257,6 +2358,7 @@
],
"summary": "List an issue's tracked times",
"operationId": "issueTrackedTimes",
"security": null,
"parameters": [
{
"type": "string",
@ -2298,6 +2400,7 @@
],
"summary": "Add a tracked time to a issue",
"operationId": "issueAddTime",
"security": null,
"parameters": [
{
"type": "string",
@ -2351,6 +2454,7 @@
],
"summary": "List a repository's keys",
"operationId": "repoListKeys",
"security": null,
"parameters": [
{
"type": "string",
@ -2385,6 +2489,7 @@
],
"summary": "Add a key to a repository",
"operationId": "repoCreateKey",
"security": null,
"parameters": [
{
"type": "string",
@ -2425,6 +2530,7 @@
],
"summary": "Get a repository's key by id",
"operationId": "repoGetKey",
"security": null,
"parameters": [
{
"type": "string",
@ -2460,6 +2566,7 @@
],
"summary": "Delete a key from a repository",
"operationId": "repoDeleteKey",
"security": null,
"parameters": [
{
"type": "string",
@ -2500,6 +2607,7 @@
],
"summary": "Get all of a repository's labels",
"operationId": "issueListLabels",
"security": null,
"parameters": [
{
"type": "string",
@ -2534,6 +2642,7 @@
],
"summary": "Create a label",
"operationId": "issueCreateLabel",
"security": null,
"parameters": [
{
"type": "string",
@ -2574,6 +2683,7 @@
],
"summary": "Get a single label",
"operationId": "issueGetLabel",
"security": null,
"parameters": [
{
"type": "string",
@ -2609,6 +2719,7 @@
],
"summary": "Delete a label",
"operationId": "issueDeleteLabel",
"security": null,
"parameters": [
{
"type": "string",
@ -2650,6 +2761,7 @@
],
"summary": "Update a label",
"operationId": "issueEditLabel",
"security": null,
"parameters": [
{
"type": "string",
@ -2697,6 +2809,7 @@
],
"summary": "Get all of a repository's milestones",
"operationId": "issueGetMilestones",
"security": null,
"parameters": [
{
"type": "string",
@ -2738,6 +2851,7 @@
],
"summary": "Create a milestone",
"operationId": "issueCreateMilestone",
"security": null,
"parameters": [
{
"type": "string",
@ -2778,6 +2892,7 @@
],
"summary": "Get a milestone",
"operationId": "issueGetMilestone",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/Milestone"
@ -2790,6 +2905,7 @@
],
"summary": "Delete a milestone",
"operationId": "issueDeleteMilestone",
"security": null,
"parameters": [
{
"type": "string",
@ -2831,6 +2947,7 @@
],
"summary": "Update a milestone",
"operationId": "issueEditMilestone",
"security": null,
"parameters": [
{
"type": "string",
@ -2871,6 +2988,7 @@
],
"summary": "Sync a mirrored repository",
"operationId": "repoMirrorSync",
"security": null,
"parameters": [
{
"type": "string",
@ -2904,6 +3022,7 @@
],
"summary": "List a repo's pull requests",
"operationId": "repoListPullRequests",
"security": null,
"parameters": [
{
"type": "string",
@ -2938,6 +3057,7 @@
],
"summary": "Create a pull request",
"operationId": "repoCreatePullRequest",
"security": null,
"parameters": [
{
"type": "string",
@ -2978,6 +3098,7 @@
],
"summary": "Get a pull request",
"operationId": "repoGetPullRequest",
"security": null,
"parameters": [
{
"type": "string",
@ -3019,6 +3140,7 @@
],
"summary": "Update a pull request",
"operationId": "repoEditPullRequest",
"security": null,
"parameters": [
{
"type": "string",
@ -3066,6 +3188,7 @@
],
"summary": "Check if a pull request has been merged",
"operationId": "repoPullRequestIsMerged",
"security": null,
"parameters": [
{
"type": "string",
@ -3113,6 +3236,7 @@
],
"summary": "Merge a pull request",
"operationId": "repoMergePullRequest",
"security": null,
"parameters": [
{
"type": "string",
@ -3156,6 +3280,7 @@
],
"summary": "Get a file from a repository",
"operationId": "repoGetRawFile",
"security": null,
"parameters": [
{
"type": "string",
@ -3197,6 +3322,7 @@
],
"summary": "Create a release",
"operationId": "repoCreateRelease",
"security": null,
"parameters": [
{
"type": "string",
@ -3234,6 +3360,7 @@
],
"summary": "Delete a release",
"operationId": "repoDeleteRelease",
"security": null,
"parameters": [
{
"type": "string",
@ -3275,6 +3402,7 @@
],
"summary": "Update a release",
"operationId": "repoEditRelease",
"security": null,
"parameters": [
{
"type": "string",
@ -3322,6 +3450,7 @@
],
"summary": "List a repo's stargazers",
"operationId": "repoListStargazers",
"security": null,
"parameters": [
{
"type": "string",
@ -3355,6 +3484,7 @@
],
"summary": "Get a commit's statuses",
"operationId": "repoListStatuses",
"security": null,
"parameters": [
{
"type": "string",
@ -3393,6 +3523,7 @@
],
"summary": "Create a commit status",
"operationId": "repoCreateStatus",
"security": null,
"parameters": [
{
"type": "string",
@ -3440,6 +3571,7 @@
],
"summary": "List a repo's watchers",
"operationId": "repoListSubscribers",
"security": null,
"parameters": [
{
"type": "string",
@ -3470,6 +3602,7 @@
],
"summary": "Check if the current user is watching a repo",
"operationId": "userCurrentCheckSubscription",
"security": null,
"parameters": [
{
"type": "string",
@ -3498,6 +3631,7 @@
],
"summary": "Watch a repo",
"operationId": "userCurrentPutSubscription",
"security": null,
"parameters": [
{
"type": "string",
@ -3526,6 +3660,7 @@
],
"summary": "Unwatch a repo",
"operationId": "userCurrentDeleteSubscription",
"security": null,
"parameters": [
{
"type": "string",
@ -3559,6 +3694,7 @@
],
"summary": "List a repo's tracked times",
"operationId": "repoTrackedTimes",
"security": null,
"parameters": [
{
"type": "string",
@ -3592,6 +3728,7 @@
],
"summary": "List a user's tracked times in a repo",
"operationId": "userTrackedTimes",
"security": null,
"parameters": [
{
"type": "string",
@ -3632,6 +3769,7 @@
],
"summary": "Delete a hook in a repository",
"operationId": "repoDeleteHook",
"security": null,
"parameters": [
{
"type": "string",
@ -3675,6 +3813,7 @@
],
"summary": "Get a repository by id",
"operationId": "repoGetByID",
"security": null,
"parameters": [
{
"type": "integer",
@ -3701,6 +3840,7 @@
],
"summary": "Get a team",
"operationId": "orgGetTeam",
"security": null,
"parameters": [
{
"type": "integer",
@ -3722,6 +3862,7 @@
],
"summary": "Delete a team",
"operationId": "orgDeleteTeam",
"security": null,
"parameters": [
{
"type": "integer",
@ -3752,6 +3893,7 @@
],
"summary": "Edit a team",
"operationId": "orgEditTeam",
"security": null,
"parameters": [
{
"type": "integer",
@ -3785,6 +3927,7 @@
],
"summary": "List a team's members",
"operationId": "orgListTeamMembers",
"security": null,
"parameters": [
{
"type": "integer",
@ -3811,6 +3954,7 @@
],
"summary": "Add a team member",
"operationId": "orgAddTeamMember",
"security": null,
"parameters": [
{
"type": "integer",
@ -3842,6 +3986,7 @@
],
"summary": "Remove a team member",
"operationId": "orgAddTeamMember",
"security": null,
"parameters": [
{
"type": "integer",
@ -3875,6 +4020,7 @@
],
"summary": "List a team's repos",
"operationId": "orgListTeamRepos",
"security": null,
"parameters": [
{
"type": "integer",
@ -3901,6 +4047,7 @@
],
"summary": "Add a repository to a team",
"operationId": "orgAddTeamMember",
"security": null,
"parameters": [
{
"type": "integer",
@ -3940,6 +4087,7 @@
],
"summary": "Remove a repository from a team",
"operationId": "orgAddTeamMember",
"security": null,
"parameters": [
{
"type": "integer",
@ -3980,6 +4128,7 @@
],
"summary": "Get the authenticated user",
"operationId": "userGetCurrent",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/User"
@ -3997,6 +4146,7 @@
],
"summary": "List the authenticated user's email addresses",
"operationId": "userListEmails",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/EmailList"
@ -4012,6 +4162,7 @@
],
"summary": "Add email addresses",
"operationId": "userAddEmail",
"security": null,
"parameters": [
{
"name": "body",
@ -4036,6 +4187,7 @@
],
"summary": "Delete email addresses",
"operationId": "userDeleteEmail",
"security": null,
"parameters": [
{
"name": "body",
@ -4062,6 +4214,7 @@
],
"summary": "List the authenticated user's followers",
"operationId": "userCurrentListFollowers",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/UserList"
@ -4079,6 +4232,7 @@
],
"summary": "List the users that the authenticated user is following",
"operationId": "userCurrentListFollowing",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/UserList"
@ -4093,6 +4247,7 @@
],
"summary": "Check whether a user is followed by the authenticated user",
"operationId": "userCurrentCheckFollowing",
"security": null,
"parameters": [
{
"type": "string",
@ -4119,6 +4274,7 @@
],
"summary": "Follow a user",
"operationId": "userCurrentPutFollow",
"security": null,
"parameters": [
{
"type": "string",
@ -4140,6 +4296,7 @@
],
"summary": "Unfollow a user",
"operationId": "userCurrentDeleteFollow",
"security": null,
"parameters": [
{
"type": "string",
@ -4166,6 +4323,7 @@
],
"summary": "List the authenticated user's GPG keys",
"operationId": "userCurrentListGPGKeys",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/GPGKeyList"
@ -4184,6 +4342,7 @@
],
"summary": "Create a GPG key",
"operationId": "userCurrentPostGPGKey",
"security": null,
"parameters": [
{
"name": "Form",
@ -4213,6 +4372,7 @@
],
"summary": "Get a GPG key",
"operationId": "userCurrentGetGPGKey",
"security": null,
"parameters": [
{
"type": "integer",
@ -4240,6 +4400,7 @@
],
"summary": "Remove a GPG key",
"operationId": "userCurrentDeleteGPGKey",
"security": null,
"parameters": [
{
"type": "integer",
@ -4269,6 +4430,7 @@
],
"summary": "List the authenticated user's public keys",
"operationId": "userCurrentListKeys",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/PublicKeyList"
@ -4287,6 +4449,7 @@
],
"summary": "Create a public key",
"operationId": "userCurrentPostKey",
"security": null,
"parameters": [
{
"name": "body",
@ -4316,6 +4479,7 @@
],
"summary": "Get a public key",
"operationId": "userCurrentGetKey",
"security": null,
"parameters": [
{
"type": "integer",
@ -4343,6 +4507,7 @@
],
"summary": "Delete a public key",
"operationId": "userCurrentDeleteKey",
"security": null,
"parameters": [
{
"type": "integer",
@ -4358,6 +4523,9 @@
},
"403": {
"$ref": "#/responses/forbidden"
},
"404": {
"$ref": "#/responses/notFound"
}
}
}
@ -4372,6 +4540,7 @@
],
"summary": "List the current user's organizations",
"operationId": "orgListCurrentUserOrgs",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/OrganizationList"
@ -4389,6 +4558,7 @@
],
"summary": "List the repos that the authenticated user owns or has access to",
"operationId": "userCurrentListRepos",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/RepositoryList"
@ -4408,6 +4578,7 @@
],
"summary": "Create a repository",
"operationId": "createCurrentUserRepo",
"security": null,
"parameters": [
{
"name": "body",
@ -4434,6 +4605,7 @@
],
"summary": "The repos that the authenticated user has starred",
"operationId": "userCurrentListStarred",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/RepositoryList"
@ -4448,6 +4620,7 @@
],
"summary": "Whether the authenticated is starring the repo",
"operationId": "userCurrentCheckStarring",
"security": null,
"parameters": [
{
"type": "string",
@ -4479,6 +4652,7 @@
],
"summary": "Star the given repo",
"operationId": "userCurrentPutStar",
"security": null,
"parameters": [
{
"type": "string",
@ -4507,6 +4681,7 @@
],
"summary": "Unstar the given repo",
"operationId": "userCurrentDeleteStar",
"security": null,
"parameters": [
{
"type": "string",
@ -4540,6 +4715,7 @@
],
"summary": "List repositories watched by the authenticated user",
"operationId": "userCurrentListSubscriptions",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/RepositoryList"
@ -4557,6 +4733,7 @@
],
"summary": "List the current user's tracked times",
"operationId": "userCurrentTrackedTimes",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/TrackedTimeList"
@ -4574,6 +4751,7 @@
],
"summary": "List a user's organizations",
"operationId": "orgListUserOrgs",
"security": null,
"parameters": [
{
"type": "string",
@ -4599,6 +4777,7 @@
],
"summary": "Search for users",
"operationId": "userSearch",
"security": null,
"parameters": [
{
"type": "string",
@ -4627,6 +4806,7 @@
],
"summary": "Check if one user is following another user",
"operationId": "userCheckFollowing",
"security": null,
"parameters": [
{
"type": "string",
@ -4663,6 +4843,7 @@
],
"summary": "Get a user",
"operationId": "userGet",
"security": null,
"parameters": [
{
"type": "string",
@ -4692,6 +4873,7 @@
],
"summary": "List the given user's followers",
"operationId": "userListFollowers",
"security": null,
"parameters": [
{
"type": "string",
@ -4718,6 +4900,7 @@
],
"summary": "List the users that the given user is following",
"operationId": "userListFollowing",
"security": null,
"parameters": [
{
"type": "string",
@ -4744,6 +4927,7 @@
],
"summary": "List the given user's GPG keys",
"operationId": "userListGPGKeys",
"security": null,
"parameters": [
{
"type": "string",
@ -4770,6 +4954,7 @@
],
"summary": "List the given user's public keys",
"operationId": "userListKeys",
"security": null,
"parameters": [
{
"type": "string",
@ -4796,6 +4981,7 @@
],
"summary": "List the repos owned by the given user",
"operationId": "userListRepos",
"security": null,
"parameters": [
{
"type": "string",
@ -4822,6 +5008,7 @@
],
"summary": "The repos that the given user has starred",
"operationId": "userListStarred",
"security": null,
"parameters": [
{
"type": "string",
@ -4848,6 +5035,7 @@
],
"summary": "List the repositories watched by a user",
"operationId": "userListSubscriptions",
"security": null,
"parameters": [
{
"type": "string",
@ -4873,6 +5061,7 @@
],
"summary": "List the authenticated user's access tokens",
"operationId": "userGetTokens",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/AccessTokenList"
@ -4891,6 +5080,7 @@
],
"summary": "Create an access token",
"operationId": "userCreateToken",
"security": null,
"parameters": [
{
"type": "string",
@ -4916,6 +5106,7 @@
],
"summary": "Returns the version of the Gitea application",
"operationId": "getVersion",
"security": null,
"responses": {
"200": {
"$ref": "#/responses/ServerVersion"
@ -6268,6 +6459,10 @@
"format": "date-time",
"x-go-name": "Created"
},
"fingerprint": {
"type": "string",
"x-go-name": "Fingerprint"
},
"id": {
"type": "integer",
"format": "int64",
@ -6281,10 +6476,6 @@
"type": "string",
"x-go-name": "Title"
},
"fingerprint": {
"type": "string",
"x-go-name": "Fingerprint"
},
"url": {
"type": "string",
"x-go-name": "URL"
@ -7182,4 +7373,4 @@
]
}
]
}
}

View File

@ -236,3 +236,48 @@ func CreatePublicKey(ctx *context.APIContext, form api.CreateKeyOption) {
}
user.CreateUserPublicKey(ctx, form, u.ID)
}
// DeleteUserPublicKey api for deleting a user's public key
func DeleteUserPublicKey(ctx *context.APIContext) {
// swagger:operation DELETE /admin/users/{username}/keys/{id} admin adminDeleteUserPublicKey
// ---
// summary: Delete a user's public key
// produces:
// - application/json
// parameters:
// - name: username
// in: path
// description: username of user
// type: string
// required: true
// - name: id
// in: path
// description: id of the key to delete
// type: integer
// required: true
// responses:
// "204":
// "$ref": "#/responses/empty"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
u := user.GetUserByParams(ctx)
if ctx.Written() {
return
}
if err := models.DeletePublicKey(u, ctx.ParamsInt64(":id")); err != nil {
if models.IsErrKeyNotExist(err) {
ctx.Status(404)
} else if models.IsErrKeyAccessDenied(err) {
ctx.Error(403, "", "You do not have access to this key")
} else {
ctx.Error(500, "DeleteUserPublicKey", err)
}
return
}
log.Trace("Key deleted by admin(%s): %s", ctx.User.Name, u.Name)
ctx.Status(204)
}

View File

@ -542,7 +542,10 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Group("/:username", func() {
m.Combo("").Patch(bind(api.EditUserOption{}), admin.EditUser).
Delete(admin.DeleteUser)
m.Post("/keys", bind(api.CreateKeyOption{}), admin.CreatePublicKey)
m.Group("/keys", func() {
m.Post("", bind(api.CreateKeyOption{}), admin.CreatePublicKey)
m.Delete("/:id", admin.DeleteUserPublicKey)
})
m.Post("/orgs", bind(api.CreateOrgOption{}), admin.CreateOrg)
m.Post("/repos", bind(api.CreateRepoOption{}), admin.CreateRepo)
})

View File

@ -178,8 +178,12 @@ func DeletePublicKey(ctx *context.APIContext) {
// "$ref": "#/responses/empty"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
if err := models.DeletePublicKey(ctx.User, ctx.ParamsInt64(":id")); err != nil {
if models.IsErrKeyAccessDenied(err) {
if models.IsErrKeyNotExist(err) {
ctx.Status(404)
} else if models.IsErrKeyAccessDenied(err) {
ctx.Error(403, "", "You do not have access to this key")
} else {
ctx.Error(500, "DeletePublicKey", err)