integration_test.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. package perm_test
  2. import (
  3. "fmt"
  4. "net/http"
  5. "net/http/httptest"
  6. "strings"
  7. "testing"
  8. "github.com/qor5/x/perm"
  9. "github.com/ory/ladon"
  10. "github.com/sunfmin/reflectutils"
  11. )
  12. type Post struct {
  13. ID uint
  14. Owner string
  15. }
  16. type MediaLibrary struct {
  17. ID uint
  18. Category string
  19. }
  20. // RN -> Resource Name
  21. func (m *MediaLibrary) PermissionRN() []string {
  22. return []string{"media_libraries", fmt.Sprint(m.ID), m.Category}
  23. }
  24. func getPost() *Post {
  25. return &Post{ID: 12, Owner: "user_123"}
  26. }
  27. func getMediaLibrary() *MediaLibrary {
  28. return &MediaLibrary{ID: 33, Category: "images"}
  29. }
  30. const Create = "Create"
  31. const Upload = "Upload"
  32. func TestPermission(t *testing.T) {
  33. perm.Verbose = true
  34. for _, c := range cases {
  35. t.Run(c.name, func(t *testing.T) {
  36. var p *perm.Builder
  37. if !c.nilBuilder {
  38. p = perm.New().Policies(c.policies...).
  39. SubjectsFunc(sf(c.subjects...)).
  40. ContextFunc(c.contextFunc)
  41. }
  42. verifier := perm.NewVerifier("presets", p)
  43. hello := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  44. post := getPost()
  45. ml := getMediaLibrary()
  46. if verifier.Do(Upload).ObjectOn(post).On("heroImage").ObjectOn(ml).WithReq(r).IsAllowed() == nil {
  47. _, _ = fmt.Fprintln(w, "upload")
  48. }
  49. if verifier.Do(Create).ObjectOn(&Post{}).WithReq(r).IsAllowed() == nil {
  50. _, _ = fmt.Fprintln(w, "create")
  51. }
  52. })
  53. w := httptest.NewRecorder()
  54. r, _ := http.NewRequest("GET", "/", nil)
  55. hello.ServeHTTP(w, r)
  56. if len(c.dontWantPermission) > 0 {
  57. if strings.Contains(w.Body.String(), c.dontWantPermission) {
  58. t.Errorf("%s should not have permission for %s, but was %s",
  59. c.subjects, c.dontWantPermission, w.Body.String())
  60. }
  61. }
  62. if len(c.wantPermission) > 0 {
  63. if !strings.Contains(w.Body.String(), c.wantPermission) {
  64. t.Errorf("%s should have permission for %s, but was %s",
  65. c.subjects, c.wantPermission, w.Body.String())
  66. }
  67. }
  68. })
  69. }
  70. }
  71. func sf(roles ...string) perm.SubjectsFunc {
  72. return func(r *http.Request) []string {
  73. return roles
  74. }
  75. }
  76. func ownerFunc(r *http.Request, objs []interface{}) perm.Context {
  77. if len(objs) > 0 {
  78. v, _ := reflectutils.Get(objs[0], "Owner")
  79. if v != nil {
  80. return perm.Context{
  81. "owner": v,
  82. }
  83. }
  84. }
  85. return nil
  86. }
  87. var cases = []struct {
  88. policies []*perm.PolicyBuilder
  89. name string
  90. subjects []string
  91. dontWantPermission string
  92. wantPermission string
  93. nilBuilder bool
  94. contextFunc perm.ContextFunc
  95. }{
  96. {
  97. name: "anonymous should not have permission for upload on posts",
  98. policies: []*perm.PolicyBuilder{
  99. perm.PolicyFor("developer").WhoAre(perm.Allowed).ToDo(Upload).On("*:posts:*"),
  100. },
  101. subjects: nil,
  102. dontWantPermission: "upload",
  103. },
  104. {
  105. name: "developer should have permission for upload on posts",
  106. policies: []*perm.PolicyBuilder{
  107. perm.PolicyFor("developer").WhoAre(perm.Allowed).ToDo(Upload).On("*:posts:*"),
  108. },
  109. subjects: []string{"developer"},
  110. wantPermission: "upload",
  111. },
  112. {
  113. name: "developer should not have permission for upload on posts",
  114. policies: []*perm.PolicyBuilder{
  115. perm.PolicyFor("developer").WhoAre(perm.Allowed).ToDo(Upload).On("*:users:*"),
  116. },
  117. subjects: []string{"developer"},
  118. dontWantPermission: "upload",
  119. },
  120. {
  121. name: "developer should have permission for upload on any posts media_libraries 33",
  122. policies: []*perm.PolicyBuilder{
  123. perm.PolicyFor("developer").WhoAre(perm.Allowed).ToDo(Upload).On("*media_libraries:33*"),
  124. },
  125. subjects: []string{"developer"},
  126. wantPermission: "upload",
  127. },
  128. {
  129. name: "developer should have permission for upload on any posts media_libraries images category",
  130. policies: []*perm.PolicyBuilder{
  131. perm.PolicyFor("developer").WhoAre(perm.Allowed).ToDo(Upload).On("*media_libraries:*:images:"),
  132. },
  133. subjects: []string{"developer"},
  134. wantPermission: "upload",
  135. },
  136. {
  137. name: "developer cant do anything",
  138. policies: []*perm.PolicyBuilder{
  139. perm.PolicyFor("developer").WhoAre(perm.Denied).ToDo(perm.Anything).On(perm.Anything),
  140. },
  141. subjects: []string{"developer"},
  142. dontWantPermission: "upload",
  143. },
  144. {
  145. name: "developer can do anything",
  146. policies: []*perm.PolicyBuilder{
  147. perm.PolicyFor("developer").WhoAre(perm.Allowed).ToDo(perm.Anything).On(perm.Anything),
  148. },
  149. subjects: []string{"developer"},
  150. wantPermission: "upload",
  151. },
  152. {
  153. name: "any body can do anything if they are owner",
  154. policies: []*perm.PolicyBuilder{
  155. perm.PolicyFor(perm.Anybody).
  156. WhoAre(perm.Allowed).ToDo(perm.Anything).On(perm.Anything).Given(
  157. perm.Conditions{
  158. "owner": &ladon.EqualsSubjectCondition{},
  159. },
  160. ),
  161. },
  162. subjects: []string{"developer", "user_123"},
  163. wantPermission: "upload",
  164. contextFunc: ownerFunc,
  165. },
  166. {
  167. name: "any body cant do anything if they are not owner",
  168. policies: []*perm.PolicyBuilder{
  169. perm.PolicyFor(perm.Anybody).
  170. WhoAre(perm.Allowed).ToDo(perm.Anything).On(perm.Anything).Given(
  171. perm.Conditions{
  172. "owner": &ladon.EqualsSubjectCondition{},
  173. },
  174. ),
  175. },
  176. subjects: []string{"developer", "user_not_owner"},
  177. dontWantPermission: "upload",
  178. contextFunc: ownerFunc,
  179. },
  180. {
  181. name: "nil builder should allow to do everything",
  182. nilBuilder: true,
  183. subjects: []string{"developer"},
  184. wantPermission: "upload",
  185. },
  186. {
  187. name: "empty policies should not allowed to do everything",
  188. policies: []*perm.PolicyBuilder{},
  189. subjects: []string{"developer"},
  190. dontWantPermission: "upload",
  191. },
  192. }