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.7KB

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