You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

key.go 6.9 kB

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package repo
  5. import (
  6. "fmt"
  7. "code.gitea.io/gitea/models"
  8. "code.gitea.io/gitea/modules/context"
  9. "code.gitea.io/gitea/modules/setting"
  10. "code.gitea.io/gitea/routers/api/v1/convert"
  11. api "code.gitea.io/sdk/gitea"
  12. )
  13. // appendPrivateInformation appends the owner and key type information to api.PublicKey
  14. func appendPrivateInformation(apiKey *api.DeployKey, key *models.DeployKey, repository *models.Repository) (*api.DeployKey, error) {
  15. apiKey.ReadOnly = key.Mode == models.AccessModeRead
  16. if repository.ID == key.RepoID {
  17. apiKey.Repository = repository.APIFormat(key.Mode)
  18. } else {
  19. repo, err := models.GetRepositoryByID(key.RepoID)
  20. if err != nil {
  21. return apiKey, err
  22. }
  23. apiKey.Repository = repo.APIFormat(key.Mode)
  24. }
  25. return apiKey, nil
  26. }
  27. func composeDeployKeysAPILink(repoPath string) string {
  28. return setting.AppURL + "api/v1/repos/" + repoPath + "/keys/"
  29. }
  30. // ListDeployKeys list all the deploy keys of a repository
  31. func ListDeployKeys(ctx *context.APIContext) {
  32. // swagger:operation GET /repos/{owner}/{repo}/keys repository repoListKeys
  33. // ---
  34. // summary: List a repository's keys
  35. // produces:
  36. // - application/json
  37. // parameters:
  38. // - name: owner
  39. // in: path
  40. // description: owner of the repo
  41. // type: string
  42. // required: true
  43. // - name: repo
  44. // in: path
  45. // description: name of the repo
  46. // type: string
  47. // required: true
  48. // - name: key_id
  49. // in: query
  50. // description: the key_id to search for
  51. // type: integer
  52. // - name: fingerprint
  53. // in: query
  54. // description: fingerprint of the key
  55. // type: string
  56. // responses:
  57. // "200":
  58. // "$ref": "#/responses/DeployKeyList"
  59. var keys []*models.DeployKey
  60. var err error
  61. fingerprint := ctx.Query("fingerprint")
  62. keyID := ctx.QueryInt64("key_id")
  63. if fingerprint != "" || keyID != 0 {
  64. keys, err = models.SearchDeployKeys(ctx.Repo.Repository.ID, keyID, fingerprint)
  65. } else {
  66. keys, err = models.ListDeployKeys(ctx.Repo.Repository.ID)
  67. }
  68. if err != nil {
  69. ctx.Error(500, "ListDeployKeys", err)
  70. return
  71. }
  72. apiLink := composeDeployKeysAPILink(ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name)
  73. apiKeys := make([]*api.DeployKey, len(keys))
  74. for i := range keys {
  75. if err = keys[i].GetContent(); err != nil {
  76. ctx.Error(500, "GetContent", err)
  77. return
  78. }
  79. apiKeys[i] = convert.ToDeployKey(apiLink, keys[i])
  80. if ctx.User.IsAdmin || ((ctx.Repo.Repository.ID == keys[i].RepoID) && (ctx.User.ID == ctx.Repo.Owner.ID)) {
  81. apiKeys[i], _ = appendPrivateInformation(apiKeys[i], keys[i], ctx.Repo.Repository)
  82. }
  83. }
  84. ctx.JSON(200, &apiKeys)
  85. }
  86. // GetDeployKey get a deploy key by id
  87. func GetDeployKey(ctx *context.APIContext) {
  88. // swagger:operation GET /repos/{owner}/{repo}/keys/{id} repository repoGetKey
  89. // ---
  90. // summary: Get a repository's key by id
  91. // produces:
  92. // - application/json
  93. // parameters:
  94. // - name: owner
  95. // in: path
  96. // description: owner of the repo
  97. // type: string
  98. // required: true
  99. // - name: repo
  100. // in: path
  101. // description: name of the repo
  102. // type: string
  103. // required: true
  104. // - name: id
  105. // in: path
  106. // description: id of the key to get
  107. // type: integer
  108. // format: int64
  109. // required: true
  110. // responses:
  111. // "200":
  112. // "$ref": "#/responses/DeployKey"
  113. key, err := models.GetDeployKeyByID(ctx.ParamsInt64(":id"))
  114. if err != nil {
  115. if models.IsErrDeployKeyNotExist(err) {
  116. ctx.Status(404)
  117. } else {
  118. ctx.Error(500, "GetDeployKeyByID", err)
  119. }
  120. return
  121. }
  122. if err = key.GetContent(); err != nil {
  123. ctx.Error(500, "GetContent", err)
  124. return
  125. }
  126. apiLink := composeDeployKeysAPILink(ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name)
  127. apiKey := convert.ToDeployKey(apiLink, key)
  128. if ctx.User.IsAdmin || ((ctx.Repo.Repository.ID == key.RepoID) && (ctx.User.ID == ctx.Repo.Owner.ID)) {
  129. apiKey, _ = appendPrivateInformation(apiKey, key, ctx.Repo.Repository)
  130. }
  131. ctx.JSON(200, apiKey)
  132. }
  133. // HandleCheckKeyStringError handle check key error
  134. func HandleCheckKeyStringError(ctx *context.APIContext, err error) {
  135. if models.IsErrSSHDisabled(err) {
  136. ctx.Error(422, "", "SSH is disabled")
  137. } else if models.IsErrKeyUnableVerify(err) {
  138. ctx.Error(422, "", "Unable to verify key content")
  139. } else {
  140. ctx.Error(422, "", fmt.Errorf("Invalid key content: %v", err))
  141. }
  142. }
  143. // HandleAddKeyError handle add key error
  144. func HandleAddKeyError(ctx *context.APIContext, err error) {
  145. switch {
  146. case models.IsErrKeyAlreadyExist(err):
  147. ctx.Error(422, "", "Key content has been used as non-deploy key")
  148. case models.IsErrKeyNameAlreadyUsed(err):
  149. ctx.Error(422, "", "Key title has been used")
  150. default:
  151. ctx.Error(500, "AddKey", err)
  152. }
  153. }
  154. // CreateDeployKey create deploy key for a repository
  155. func CreateDeployKey(ctx *context.APIContext, form api.CreateKeyOption) {
  156. // swagger:operation POST /repos/{owner}/{repo}/keys repository repoCreateKey
  157. // ---
  158. // summary: Add a key to a repository
  159. // consumes:
  160. // - application/json
  161. // produces:
  162. // - application/json
  163. // parameters:
  164. // - name: owner
  165. // in: path
  166. // description: owner of the repo
  167. // type: string
  168. // required: true
  169. // - name: repo
  170. // in: path
  171. // description: name of the repo
  172. // type: string
  173. // required: true
  174. // - name: body
  175. // in: body
  176. // schema:
  177. // "$ref": "#/definitions/CreateKeyOption"
  178. // responses:
  179. // "201":
  180. // "$ref": "#/responses/DeployKey"
  181. content, err := models.CheckPublicKeyString(form.Key)
  182. if err != nil {
  183. HandleCheckKeyStringError(ctx, err)
  184. return
  185. }
  186. key, err := models.AddDeployKey(ctx.Repo.Repository.ID, form.Title, content, form.ReadOnly)
  187. if err != nil {
  188. HandleAddKeyError(ctx, err)
  189. return
  190. }
  191. key.Content = content
  192. apiLink := composeDeployKeysAPILink(ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name)
  193. ctx.JSON(201, convert.ToDeployKey(apiLink, key))
  194. }
  195. // DeleteDeploykey delete deploy key for a repository
  196. func DeleteDeploykey(ctx *context.APIContext) {
  197. // swagger:operation DELETE /repos/{owner}/{repo}/keys/{id} repository repoDeleteKey
  198. // ---
  199. // summary: Delete a key from a repository
  200. // parameters:
  201. // - name: owner
  202. // in: path
  203. // description: owner of the repo
  204. // type: string
  205. // required: true
  206. // - name: repo
  207. // in: path
  208. // description: name of the repo
  209. // type: string
  210. // required: true
  211. // - name: id
  212. // in: path
  213. // description: id of the key to delete
  214. // type: integer
  215. // format: int64
  216. // required: true
  217. // responses:
  218. // "204":
  219. // "$ref": "#/responses/empty"
  220. if err := models.DeleteDeployKey(ctx.User, ctx.ParamsInt64(":id")); err != nil {
  221. if models.IsErrKeyAccessDenied(err) {
  222. ctx.Error(403, "", "You do not have access to this key")
  223. } else {
  224. ctx.Error(500, "DeleteDeployKey", err)
  225. }
  226. return
  227. }
  228. ctx.Status(204)
  229. }