permset.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Package permset provides primitives for permission management.
  2. package permset
  3. import (
  4. "context"
  5. "fmt"
  6. )
  7. // Perm is a permission to do some action.
  8. type Perm int
  9. // Permset represents a set of permissions.
  10. type Permset struct {
  11. permset map[Perm]bool
  12. }
  13. // New receives permissions to contain and returns a permset from it.
  14. func New(perms ...Perm) Permset {
  15. permset := Permset{permset: make(map[Perm]bool)}
  16. permset.Add(perms...)
  17. return permset
  18. }
  19. // Add adds the received perms to the permset.
  20. func (ps *Permset) Add(perms ...Perm) {
  21. for _, perm := range perms {
  22. ps.permset[perm] = true
  23. }
  24. }
  25. // Remove removes the received perms from the permset.
  26. func (ps *Permset) Remove(perms ...Perm) {
  27. for _, perm := range perms {
  28. if _, ok := ps.permset[perm]; ok {
  29. delete(ps.permset, perm)
  30. }
  31. }
  32. }
  33. // Perms returns the permissions contained within the permset.
  34. func (ps *Permset) Perms() []Perm {
  35. var perms []Perm
  36. for k := range ps.permset {
  37. perms = append(perms, k)
  38. }
  39. return perms
  40. }
  41. // Contains receives single Perm and returns true if the permset contains it.
  42. func (ps *Permset) Contains(perm Perm) bool {
  43. if _, ok := ps.permset[perm]; !ok {
  44. return false
  45. }
  46. return true
  47. }
  48. // ContainsAll returns true if the permset contains all received Perms.
  49. func (ps *Permset) ContainsAll(perms ...Perm) bool {
  50. for _, perm := range perms {
  51. if _, ok := ps.permset[perm]; !ok {
  52. return false
  53. }
  54. }
  55. return true
  56. }
  57. // ContainsSome returns true if the permset contains any one or more of the received Perms.
  58. func (ps *Permset) ContainsSome(perms ...Perm) bool {
  59. for _, perm := range perms {
  60. if _, ok := ps.permset[perm]; ok {
  61. return true
  62. }
  63. }
  64. return false
  65. }
  66. // ContainsNone returns true if the permset contains none one of the received Perms.
  67. func (ps *Permset) ContainsNone(perms ...Perm) bool {
  68. for _, perm := range perms {
  69. if _, ok := ps.permset[perm]; ok {
  70. return false
  71. }
  72. }
  73. return true
  74. }
  75. type permsetKeyType int
  76. const permsetKey permsetKeyType = iota
  77. // NewContext receives perms and returns a context with the received perms are the value of the context.
  78. func NewContext(ctx context.Context, permset Permset) context.Context {
  79. return context.WithValue(ctx, permsetKey, permset)
  80. }
  81. // FromContext receives a context and returns the permset in it.
  82. func FromContext(ctx context.Context) (Permset, error) {
  83. permset, ok := ctx.Value(permsetKey).(Permset)
  84. if !ok {
  85. return Permset{}, fmt.Errorf("cannot get context value")
  86. }
  87. return permset, nil
  88. }