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

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