role.go 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Copyright (C) 2019-2023 Nicola Murino
  2. //
  3. // This program is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU Affero General Public License as published
  5. // by the Free Software Foundation, version 3.
  6. //
  7. // This program is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU Affero General Public License for more details.
  11. //
  12. // You should have received a copy of the GNU Affero General Public License
  13. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. package dataprovider
  15. import (
  16. "encoding/json"
  17. "fmt"
  18. "strings"
  19. "github.com/drakkan/sftpgo/v2/internal/logger"
  20. "github.com/drakkan/sftpgo/v2/internal/util"
  21. )
  22. // Role defines an SFTPGo role.
  23. type Role struct {
  24. // Data provider unique identifier
  25. ID int64 `json:"id"`
  26. // Role name
  27. Name string `json:"name"`
  28. // optional description
  29. Description string `json:"description,omitempty"`
  30. // Creation time as unix timestamp in milliseconds
  31. CreatedAt int64 `json:"created_at"`
  32. // last update time as unix timestamp in milliseconds
  33. UpdatedAt int64 `json:"updated_at"`
  34. // list of admins associated with this role
  35. Admins []string `json:"admins,omitempty"`
  36. // list of usernames associated with this role
  37. Users []string `json:"users,omitempty"`
  38. }
  39. // RenderAsJSON implements the renderer interface used within plugins
  40. func (r *Role) RenderAsJSON(reload bool) ([]byte, error) {
  41. if reload {
  42. role, err := provider.roleExists(r.Name)
  43. if err != nil {
  44. providerLog(logger.LevelError, "unable to reload role before rendering as json: %v", err)
  45. return nil, err
  46. }
  47. return json.Marshal(role)
  48. }
  49. return json.Marshal(r)
  50. }
  51. func (r *Role) validate() error {
  52. if r.Name == "" {
  53. return util.NewValidationError("name is mandatory")
  54. }
  55. if len(r.Name) > 255 {
  56. return util.NewValidationError("name is too long, 255 is the maximum length allowed")
  57. }
  58. if config.NamingRules&1 == 0 && !usernameRegex.MatchString(r.Name) {
  59. return util.NewValidationError(fmt.Sprintf("name %q is not valid, the following characters are allowed: a-zA-Z0-9-_.~", r.Name))
  60. }
  61. return nil
  62. }
  63. func (r *Role) getACopy() Role {
  64. users := make([]string, len(r.Users))
  65. copy(users, r.Users)
  66. admins := make([]string, len(r.Admins))
  67. copy(admins, r.Admins)
  68. return Role{
  69. ID: r.ID,
  70. Name: r.Name,
  71. Description: r.Description,
  72. CreatedAt: r.CreatedAt,
  73. UpdatedAt: r.UpdatedAt,
  74. Users: users,
  75. Admins: admins,
  76. }
  77. }
  78. // GetMembersAsString returns a string representation for the role members
  79. func (r *Role) GetMembersAsString() string {
  80. var sb strings.Builder
  81. if len(r.Users) > 0 {
  82. sb.WriteString(fmt.Sprintf("Users: %d. ", len(r.Users)))
  83. }
  84. if len(r.Admins) > 0 {
  85. sb.WriteString(fmt.Sprintf("Admins: %d. ", len(r.Admins)))
  86. }
  87. return sb.String()
  88. }