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.

ssh_key_principals.go 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package asymkey
  4. import (
  5. "errors"
  6. "fmt"
  7. "strings"
  8. "code.gitea.io/gitea/models/db"
  9. "code.gitea.io/gitea/models/perm"
  10. user_model "code.gitea.io/gitea/models/user"
  11. "code.gitea.io/gitea/modules/setting"
  12. )
  13. // __________ .__ .__ .__
  14. // \______ _______|__| ____ ____ |_____________ | | ______
  15. // | ___\_ __ | |/ \_/ ___\| \____ \__ \ | | / ___/
  16. // | | | | \| | | \ \___| | |_> / __ \| |__\___ \
  17. // |____| |__| |__|___| /\___ |__| __(____ |____/____ >
  18. // \/ \/ |__| \/ \/
  19. //
  20. // This file contains functions related to principals
  21. // AddPrincipalKey adds new principal to database and authorized_principals file.
  22. func AddPrincipalKey(ownerID int64, content string, authSourceID int64) (*PublicKey, error) {
  23. ctx, committer, err := db.TxContext(db.DefaultContext)
  24. if err != nil {
  25. return nil, err
  26. }
  27. defer committer.Close()
  28. // Principals cannot be duplicated.
  29. has, err := db.GetEngine(ctx).
  30. Where("content = ? AND type = ?", content, KeyTypePrincipal).
  31. Get(new(PublicKey))
  32. if err != nil {
  33. return nil, err
  34. } else if has {
  35. return nil, ErrKeyAlreadyExist{0, "", content}
  36. }
  37. key := &PublicKey{
  38. OwnerID: ownerID,
  39. Name: content,
  40. Content: content,
  41. Mode: perm.AccessModeWrite,
  42. Type: KeyTypePrincipal,
  43. LoginSourceID: authSourceID,
  44. }
  45. if err = db.Insert(ctx, key); err != nil {
  46. return nil, fmt.Errorf("addKey: %w", err)
  47. }
  48. if err = committer.Commit(); err != nil {
  49. return nil, err
  50. }
  51. committer.Close()
  52. return key, RewriteAllPrincipalKeys(db.DefaultContext)
  53. }
  54. // CheckPrincipalKeyString strips spaces and returns an error if the given principal contains newlines
  55. func CheckPrincipalKeyString(user *user_model.User, content string) (_ string, err error) {
  56. if setting.SSH.Disabled {
  57. return "", db.ErrSSHDisabled{}
  58. }
  59. content = strings.TrimSpace(content)
  60. if strings.ContainsAny(content, "\r\n") {
  61. return "", errors.New("only a single line with a single principal please")
  62. }
  63. // check all the allowed principals, email, username or anything
  64. // if any matches, return ok
  65. for _, v := range setting.SSH.AuthorizedPrincipalsAllow {
  66. switch v {
  67. case "anything":
  68. return content, nil
  69. case "email":
  70. emails, err := user_model.GetEmailAddresses(user.ID)
  71. if err != nil {
  72. return "", err
  73. }
  74. for _, email := range emails {
  75. if !email.IsActivated {
  76. continue
  77. }
  78. if content == email.Email {
  79. return content, nil
  80. }
  81. }
  82. case "username":
  83. if content == user.Name {
  84. return content, nil
  85. }
  86. }
  87. }
  88. return "", fmt.Errorf("didn't match allowed principals: %s", setting.SSH.AuthorizedPrincipalsAllow)
  89. }
  90. // ListPrincipalKeys returns a list of principals belongs to given user.
  91. func ListPrincipalKeys(uid int64, listOptions db.ListOptions) ([]*PublicKey, error) {
  92. sess := db.GetEngine(db.DefaultContext).Where("owner_id = ? AND type = ?", uid, KeyTypePrincipal)
  93. if listOptions.Page != 0 {
  94. sess = db.SetSessionPagination(sess, &listOptions)
  95. keys := make([]*PublicKey, 0, listOptions.PageSize)
  96. return keys, sess.Find(&keys)
  97. }
  98. keys := make([]*PublicKey, 0, 5)
  99. return keys, sess.Find(&keys)
  100. }