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

key.go 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  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 user
  5. import (
  6. "net/http"
  7. "code.gitea.io/gitea/models"
  8. "code.gitea.io/gitea/modules/context"
  9. "code.gitea.io/gitea/modules/convert"
  10. "code.gitea.io/gitea/modules/setting"
  11. api "code.gitea.io/gitea/modules/structs"
  12. "code.gitea.io/gitea/routers/api/v1/repo"
  13. "code.gitea.io/gitea/routers/api/v1/utils"
  14. )
  15. // appendPrivateInformation appends the owner and key type information to api.PublicKey
  16. func appendPrivateInformation(apiKey *api.PublicKey, key *models.PublicKey, defaultUser *models.User) (*api.PublicKey, error) {
  17. if key.Type == models.KeyTypeDeploy {
  18. apiKey.KeyType = "deploy"
  19. } else if key.Type == models.KeyTypeUser {
  20. apiKey.KeyType = "user"
  21. if defaultUser.ID == key.OwnerID {
  22. apiKey.Owner = convert.ToUser(defaultUser, true, true)
  23. } else {
  24. user, err := models.GetUserByID(key.OwnerID)
  25. if err != nil {
  26. return apiKey, err
  27. }
  28. apiKey.Owner = convert.ToUser(user, true, true)
  29. }
  30. } else {
  31. apiKey.KeyType = "unknown"
  32. }
  33. apiKey.ReadOnly = key.Mode == models.AccessModeRead
  34. return apiKey, nil
  35. }
  36. func composePublicKeysAPILink() string {
  37. return setting.AppURL + "api/v1/user/keys/"
  38. }
  39. func listPublicKeys(ctx *context.APIContext, user *models.User) {
  40. var keys []*models.PublicKey
  41. var err error
  42. fingerprint := ctx.Query("fingerprint")
  43. username := ctx.Params("username")
  44. if fingerprint != "" {
  45. // Querying not just listing
  46. if username != "" {
  47. // Restrict to provided uid
  48. keys, err = models.SearchPublicKey(user.ID, fingerprint)
  49. } else {
  50. // Unrestricted
  51. keys, err = models.SearchPublicKey(0, fingerprint)
  52. }
  53. } else {
  54. // Use ListPublicKeys
  55. keys, err = models.ListPublicKeys(user.ID, utils.GetListOptions(ctx))
  56. }
  57. if err != nil {
  58. ctx.Error(http.StatusInternalServerError, "ListPublicKeys", err)
  59. return
  60. }
  61. apiLink := composePublicKeysAPILink()
  62. apiKeys := make([]*api.PublicKey, len(keys))
  63. for i := range keys {
  64. apiKeys[i] = convert.ToPublicKey(apiLink, keys[i])
  65. if ctx.User.IsAdmin || ctx.User.ID == keys[i].OwnerID {
  66. apiKeys[i], _ = appendPrivateInformation(apiKeys[i], keys[i], user)
  67. }
  68. }
  69. ctx.JSON(http.StatusOK, &apiKeys)
  70. }
  71. // ListMyPublicKeys list all of the authenticated user's public keys
  72. func ListMyPublicKeys(ctx *context.APIContext) {
  73. // swagger:operation GET /user/keys user userCurrentListKeys
  74. // ---
  75. // summary: List the authenticated user's public keys
  76. // parameters:
  77. // - name: fingerprint
  78. // in: query
  79. // description: fingerprint of the key
  80. // type: string
  81. // - name: page
  82. // in: query
  83. // description: page number of results to return (1-based)
  84. // type: integer
  85. // - name: limit
  86. // in: query
  87. // description: page size of results
  88. // type: integer
  89. // produces:
  90. // - application/json
  91. // responses:
  92. // "200":
  93. // "$ref": "#/responses/PublicKeyList"
  94. listPublicKeys(ctx, ctx.User)
  95. }
  96. // ListPublicKeys list the given user's public keys
  97. func ListPublicKeys(ctx *context.APIContext) {
  98. // swagger:operation GET /users/{username}/keys user userListKeys
  99. // ---
  100. // summary: List the given user's public keys
  101. // produces:
  102. // - application/json
  103. // parameters:
  104. // - name: username
  105. // in: path
  106. // description: username of user
  107. // type: string
  108. // required: true
  109. // - name: fingerprint
  110. // in: query
  111. // description: fingerprint of the key
  112. // type: string
  113. // - name: page
  114. // in: query
  115. // description: page number of results to return (1-based)
  116. // type: integer
  117. // - name: limit
  118. // in: query
  119. // description: page size of results
  120. // type: integer
  121. // responses:
  122. // "200":
  123. // "$ref": "#/responses/PublicKeyList"
  124. user := GetUserByParams(ctx)
  125. if ctx.Written() {
  126. return
  127. }
  128. listPublicKeys(ctx, user)
  129. }
  130. // GetPublicKey get a public key
  131. func GetPublicKey(ctx *context.APIContext) {
  132. // swagger:operation GET /user/keys/{id} user userCurrentGetKey
  133. // ---
  134. // summary: Get a public key
  135. // produces:
  136. // - application/json
  137. // parameters:
  138. // - name: id
  139. // in: path
  140. // description: id of key to get
  141. // type: integer
  142. // format: int64
  143. // required: true
  144. // responses:
  145. // "200":
  146. // "$ref": "#/responses/PublicKey"
  147. // "404":
  148. // "$ref": "#/responses/notFound"
  149. key, err := models.GetPublicKeyByID(ctx.ParamsInt64(":id"))
  150. if err != nil {
  151. if models.IsErrKeyNotExist(err) {
  152. ctx.NotFound()
  153. } else {
  154. ctx.Error(http.StatusInternalServerError, "GetPublicKeyByID", err)
  155. }
  156. return
  157. }
  158. apiLink := composePublicKeysAPILink()
  159. apiKey := convert.ToPublicKey(apiLink, key)
  160. if ctx.User.IsAdmin || ctx.User.ID == key.OwnerID {
  161. apiKey, _ = appendPrivateInformation(apiKey, key, ctx.User)
  162. }
  163. ctx.JSON(http.StatusOK, apiKey)
  164. }
  165. // CreateUserPublicKey creates new public key to given user by ID.
  166. func CreateUserPublicKey(ctx *context.APIContext, form api.CreateKeyOption, uid int64) {
  167. content, err := models.CheckPublicKeyString(form.Key)
  168. if err != nil {
  169. repo.HandleCheckKeyStringError(ctx, err)
  170. return
  171. }
  172. key, err := models.AddPublicKey(uid, form.Title, content, 0)
  173. if err != nil {
  174. repo.HandleAddKeyError(ctx, err)
  175. return
  176. }
  177. apiLink := composePublicKeysAPILink()
  178. apiKey := convert.ToPublicKey(apiLink, key)
  179. if ctx.User.IsAdmin || ctx.User.ID == key.OwnerID {
  180. apiKey, _ = appendPrivateInformation(apiKey, key, ctx.User)
  181. }
  182. ctx.JSON(http.StatusCreated, apiKey)
  183. }
  184. // CreatePublicKey create one public key for me
  185. func CreatePublicKey(ctx *context.APIContext, form api.CreateKeyOption) {
  186. // swagger:operation POST /user/keys user userCurrentPostKey
  187. // ---
  188. // summary: Create a public key
  189. // consumes:
  190. // - application/json
  191. // produces:
  192. // - application/json
  193. // parameters:
  194. // - name: body
  195. // in: body
  196. // schema:
  197. // "$ref": "#/definitions/CreateKeyOption"
  198. // responses:
  199. // "201":
  200. // "$ref": "#/responses/PublicKey"
  201. // "422":
  202. // "$ref": "#/responses/validationError"
  203. CreateUserPublicKey(ctx, form, ctx.User.ID)
  204. }
  205. // DeletePublicKey delete one public key
  206. func DeletePublicKey(ctx *context.APIContext) {
  207. // swagger:operation DELETE /user/keys/{id} user userCurrentDeleteKey
  208. // ---
  209. // summary: Delete a public key
  210. // produces:
  211. // - application/json
  212. // parameters:
  213. // - name: id
  214. // in: path
  215. // description: id of key to delete
  216. // type: integer
  217. // format: int64
  218. // required: true
  219. // responses:
  220. // "204":
  221. // "$ref": "#/responses/empty"
  222. // "403":
  223. // "$ref": "#/responses/forbidden"
  224. // "404":
  225. // "$ref": "#/responses/notFound"
  226. id := ctx.ParamsInt64(":id")
  227. externallyManaged, err := models.PublicKeyIsExternallyManaged(id)
  228. if err != nil {
  229. ctx.Error(http.StatusInternalServerError, "PublicKeyIsExternallyManaged", err)
  230. }
  231. if externallyManaged {
  232. ctx.Error(http.StatusForbidden, "", "SSH Key is externally managed for this user")
  233. }
  234. if err := models.DeletePublicKey(ctx.User, id); err != nil {
  235. if models.IsErrKeyNotExist(err) {
  236. ctx.NotFound()
  237. } else if models.IsErrKeyAccessDenied(err) {
  238. ctx.Error(http.StatusForbidden, "", "You do not have access to this key")
  239. } else {
  240. ctx.Error(http.StatusInternalServerError, "DeletePublicKey", err)
  241. }
  242. return
  243. }
  244. ctx.Status(http.StatusNoContent)
  245. }