loader.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package policy
  2. import (
  3. "fmt"
  4. "github.com/porter-dev/porter/api/server/shared/apierrors"
  5. "github.com/porter-dev/porter/api/types"
  6. "github.com/porter-dev/porter/internal/models"
  7. "github.com/porter-dev/porter/internal/repository"
  8. "gorm.io/gorm"
  9. )
  10. type PolicyLoaderOpts struct {
  11. ProjectID, UserID uint
  12. Token *models.APIToken
  13. }
  14. type PolicyDocumentLoader interface {
  15. LoadPolicyDocuments(opts *PolicyLoaderOpts) ([]*types.PolicyDocument, apierrors.RequestError)
  16. }
  17. // RepoPolicyDocumentLoader loads policy documents by reading from the repository database
  18. type RepoPolicyDocumentLoader struct {
  19. projRepo repository.ProjectRepository
  20. policyRepo repository.PolicyRepository
  21. }
  22. func NewBasicPolicyDocumentLoader(projRepo repository.ProjectRepository, policyRepo repository.PolicyRepository) *RepoPolicyDocumentLoader {
  23. return &RepoPolicyDocumentLoader{projRepo, policyRepo}
  24. }
  25. func (b *RepoPolicyDocumentLoader) LoadPolicyDocuments(
  26. opts *PolicyLoaderOpts,
  27. ) ([]*types.PolicyDocument, apierrors.RequestError) {
  28. if opts.Token != nil {
  29. // load the policy from the repo
  30. policy, err := b.policyRepo.ReadPolicy(opts.Token.ProjectID, opts.Token.PolicyUID)
  31. if err != nil {
  32. return nil, apierrors.NewErrInternal(err)
  33. }
  34. apiPolicy, err := policy.ToAPIPolicyType()
  35. if err != nil {
  36. return nil, apierrors.NewErrInternal(err)
  37. }
  38. return apiPolicy.Policy, nil
  39. } else if opts.ProjectID != 0 && opts.UserID != 0 {
  40. userID := opts.UserID
  41. projectID := opts.ProjectID
  42. // read role and case on role "kind"
  43. role, err := b.projRepo.ReadProjectRole(projectID, userID)
  44. if err != nil && err == gorm.ErrRecordNotFound {
  45. return nil, apierrors.NewErrForbidden(
  46. fmt.Errorf("user %d does not have a role in project %d", userID, projectID),
  47. )
  48. } else if err != nil {
  49. return nil, apierrors.NewErrInternal(err)
  50. }
  51. // load role based on role kind
  52. switch role.Kind {
  53. case types.RoleAdmin:
  54. return AdminPolicy, nil
  55. case types.RoleDeveloper:
  56. return DeveloperPolicy, nil
  57. case types.RoleViewer:
  58. return ViewerPolicy, nil
  59. default:
  60. return nil, apierrors.NewErrForbidden(
  61. fmt.Errorf("%s role not supported for user %d, project %d", string(role.Kind), userID, projectID),
  62. )
  63. }
  64. }
  65. return nil, apierrors.NewErrForbidden(
  66. fmt.Errorf("policy loader called with invalid arguments"),
  67. )
  68. }
  69. var AdminPolicy = []*types.PolicyDocument{
  70. {
  71. Scope: types.ProjectScope,
  72. Verbs: types.ReadWriteVerbGroup(),
  73. },
  74. }
  75. var DeveloperPolicy = []*types.PolicyDocument{
  76. {
  77. Scope: types.ProjectScope,
  78. Verbs: types.ReadWriteVerbGroup(),
  79. Children: map[types.PermissionScope]*types.PolicyDocument{
  80. types.SettingsScope: {
  81. Scope: types.SettingsScope,
  82. Verbs: types.ReadVerbGroup(),
  83. },
  84. },
  85. },
  86. }
  87. var ViewerPolicy = []*types.PolicyDocument{
  88. {
  89. Scope: types.ProjectScope,
  90. Verbs: types.ReadVerbGroup(),
  91. Children: map[types.PermissionScope]*types.PolicyDocument{
  92. types.SettingsScope: {
  93. Scope: types.SettingsScope,
  94. Verbs: []types.APIVerb{},
  95. },
  96. },
  97. },
  98. }