00533d3870
* Add private information to the deploy keys api This commit adds more information to the deploy keys to allow for back reference in to the main keys list. It also adds information about the repository that the key is referring to. Signed-off-by: Andrew Thornton <art27@cantab.net> * Add private information to the user keys API This adjusts the keys API to give out private information to user keys if the current user is the owner or an admin. Signed-off-by: Andrew Thornton <art27@cantab.net> * Add ability to search keys by fingerprint This commit adds the functionality to search ssh-keys by fingerprint of the ssh-key. Deploy keys per repository can also be searched. There is no current clear API point to allow search of all deploy keys by fingerprint or keyID. Signed-off-by: Andrew Thornton <art27@cantab.net> * Add integration test
260 lines
6.7 KiB
Go
260 lines
6.7 KiB
Go
// Copyright 2015 The Gogs 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 user
|
|
|
|
import (
|
|
api "code.gitea.io/sdk/gitea"
|
|
|
|
"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"
|
|
"code.gitea.io/gitea/routers/api/v1/repo"
|
|
)
|
|
|
|
// appendPrivateInformation appends the owner and key type information to api.PublicKey
|
|
func appendPrivateInformation(apiKey *api.PublicKey, key *models.PublicKey, defaultUser *models.User) (*api.PublicKey, error) {
|
|
if key.Type == models.KeyTypeDeploy {
|
|
apiKey.KeyType = "deploy"
|
|
} else if key.Type == models.KeyTypeUser {
|
|
apiKey.KeyType = "user"
|
|
|
|
if defaultUser.ID == key.OwnerID {
|
|
apiKey.Owner = defaultUser.APIFormat()
|
|
} else {
|
|
user, err := models.GetUserByID(key.OwnerID)
|
|
if err != nil {
|
|
return apiKey, err
|
|
}
|
|
apiKey.Owner = user.APIFormat()
|
|
}
|
|
} else {
|
|
apiKey.KeyType = "unknown"
|
|
}
|
|
apiKey.ReadOnly = key.Mode == models.AccessModeRead
|
|
return apiKey, nil
|
|
}
|
|
|
|
// GetUserByParamsName get user by name
|
|
func GetUserByParamsName(ctx *context.APIContext, name string) *models.User {
|
|
user, err := models.GetUserByName(ctx.Params(name))
|
|
if err != nil {
|
|
if models.IsErrUserNotExist(err) {
|
|
ctx.Status(404)
|
|
} else {
|
|
ctx.Error(500, "GetUserByName", err)
|
|
}
|
|
return nil
|
|
}
|
|
return user
|
|
}
|
|
|
|
// GetUserByParams returns user whose name is presented in URL paramenter.
|
|
func GetUserByParams(ctx *context.APIContext) *models.User {
|
|
return GetUserByParamsName(ctx, ":username")
|
|
}
|
|
|
|
func composePublicKeysAPILink() string {
|
|
return setting.AppURL + "api/v1/user/keys/"
|
|
}
|
|
|
|
func listPublicKeys(ctx *context.APIContext, user *models.User) {
|
|
var keys []*models.PublicKey
|
|
var err error
|
|
|
|
fingerprint := ctx.Query("fingerprint")
|
|
username := ctx.Params("username")
|
|
|
|
if fingerprint != "" {
|
|
// Querying not just listing
|
|
if username != "" {
|
|
// Restrict to provided uid
|
|
keys, err = models.SearchPublicKey(user.ID, fingerprint)
|
|
} else {
|
|
// Unrestricted
|
|
keys, err = models.SearchPublicKey(0, fingerprint)
|
|
}
|
|
} else {
|
|
// Use ListPublicKeys
|
|
keys, err = models.ListPublicKeys(user.ID)
|
|
}
|
|
|
|
if err != nil {
|
|
ctx.Error(500, "ListPublicKeys", err)
|
|
return
|
|
}
|
|
|
|
apiLink := composePublicKeysAPILink()
|
|
apiKeys := make([]*api.PublicKey, len(keys))
|
|
for i := range keys {
|
|
apiKeys[i] = convert.ToPublicKey(apiLink, keys[i])
|
|
if ctx.User.IsAdmin || ctx.User.ID == keys[i].OwnerID {
|
|
apiKeys[i], _ = appendPrivateInformation(apiKeys[i], keys[i], user)
|
|
}
|
|
}
|
|
|
|
ctx.JSON(200, &apiKeys)
|
|
}
|
|
|
|
// ListMyPublicKeys list all of the authenticated user's public keys
|
|
func ListMyPublicKeys(ctx *context.APIContext) {
|
|
// swagger:operation GET /user/keys user userCurrentListKeys
|
|
// ---
|
|
// summary: List the authenticated user's public keys
|
|
// parameters:
|
|
// - name: fingerprint
|
|
// in: query
|
|
// description: fingerprint of the key
|
|
// type: string
|
|
// produces:
|
|
// - application/json
|
|
// responses:
|
|
// "200":
|
|
// "$ref": "#/responses/PublicKeyList"
|
|
listPublicKeys(ctx, ctx.User)
|
|
}
|
|
|
|
// ListPublicKeys list the given user's public keys
|
|
func ListPublicKeys(ctx *context.APIContext) {
|
|
// swagger:operation GET /users/{username}/keys user userListKeys
|
|
// ---
|
|
// summary: List the given user's public keys
|
|
// produces:
|
|
// - application/json
|
|
// parameters:
|
|
// - name: username
|
|
// in: path
|
|
// description: username of user
|
|
// type: string
|
|
// required: true
|
|
// - name: fingerprint
|
|
// in: query
|
|
// description: fingerprint of the key
|
|
// type: string
|
|
// responses:
|
|
// "200":
|
|
// "$ref": "#/responses/PublicKeyList"
|
|
user := GetUserByParams(ctx)
|
|
if ctx.Written() {
|
|
return
|
|
}
|
|
listPublicKeys(ctx, user)
|
|
}
|
|
|
|
// GetPublicKey get a public key
|
|
func GetPublicKey(ctx *context.APIContext) {
|
|
// swagger:operation GET /user/keys/{id} user userCurrentGetKey
|
|
// ---
|
|
// summary: Get a public key
|
|
// produces:
|
|
// - application/json
|
|
// parameters:
|
|
// - name: id
|
|
// in: path
|
|
// description: id of key to get
|
|
// type: integer
|
|
// format: int64
|
|
// required: true
|
|
// responses:
|
|
// "200":
|
|
// "$ref": "#/responses/PublicKey"
|
|
// "404":
|
|
// "$ref": "#/responses/notFound"
|
|
key, err := models.GetPublicKeyByID(ctx.ParamsInt64(":id"))
|
|
if err != nil {
|
|
if models.IsErrKeyNotExist(err) {
|
|
ctx.Status(404)
|
|
} else {
|
|
ctx.Error(500, "GetPublicKeyByID", err)
|
|
}
|
|
return
|
|
}
|
|
|
|
apiLink := composePublicKeysAPILink()
|
|
apiKey := convert.ToPublicKey(apiLink, key)
|
|
if ctx.User.IsAdmin || ctx.User.ID == key.OwnerID {
|
|
apiKey, _ = appendPrivateInformation(apiKey, key, ctx.User)
|
|
}
|
|
ctx.JSON(200, apiKey)
|
|
}
|
|
|
|
// CreateUserPublicKey creates new public key to given user by ID.
|
|
func CreateUserPublicKey(ctx *context.APIContext, form api.CreateKeyOption, uid int64) {
|
|
content, err := models.CheckPublicKeyString(form.Key)
|
|
if err != nil {
|
|
repo.HandleCheckKeyStringError(ctx, err)
|
|
return
|
|
}
|
|
|
|
key, err := models.AddPublicKey(uid, form.Title, content, 0)
|
|
if err != nil {
|
|
repo.HandleAddKeyError(ctx, err)
|
|
return
|
|
}
|
|
apiLink := composePublicKeysAPILink()
|
|
apiKey := convert.ToPublicKey(apiLink, key)
|
|
if ctx.User.IsAdmin || ctx.User.ID == key.OwnerID {
|
|
apiKey, _ = appendPrivateInformation(apiKey, key, ctx.User)
|
|
}
|
|
ctx.JSON(201, apiKey)
|
|
}
|
|
|
|
// CreatePublicKey create one public key for me
|
|
func CreatePublicKey(ctx *context.APIContext, form api.CreateKeyOption) {
|
|
// swagger:operation POST /user/keys user userCurrentPostKey
|
|
// ---
|
|
// summary: Create a public key
|
|
// consumes:
|
|
// - application/json
|
|
// produces:
|
|
// - application/json
|
|
// parameters:
|
|
// - name: body
|
|
// in: body
|
|
// schema:
|
|
// "$ref": "#/definitions/CreateKeyOption"
|
|
// responses:
|
|
// "201":
|
|
// "$ref": "#/responses/PublicKey"
|
|
// "422":
|
|
// "$ref": "#/responses/validationError"
|
|
CreateUserPublicKey(ctx, form, ctx.User.ID)
|
|
}
|
|
|
|
// DeletePublicKey delete one public key
|
|
func DeletePublicKey(ctx *context.APIContext) {
|
|
// swagger:operation DELETE /user/keys/{id} user userCurrentDeleteKey
|
|
// ---
|
|
// summary: Delete a public key
|
|
// produces:
|
|
// - application/json
|
|
// parameters:
|
|
// - name: id
|
|
// in: path
|
|
// description: id of key to delete
|
|
// type: integer
|
|
// format: int64
|
|
// required: true
|
|
// responses:
|
|
// "204":
|
|
// "$ref": "#/responses/empty"
|
|
// "403":
|
|
// "$ref": "#/responses/forbidden"
|
|
// "404":
|
|
// "$ref": "#/responses/notFound"
|
|
if err := models.DeletePublicKey(ctx.User, 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, "DeletePublicKey", err)
|
|
}
|
|
return
|
|
}
|
|
|
|
ctx.Status(204)
|
|
}
|