util.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * ECAL
  3. *
  4. * Copyright 2020 Matthias Ladkau. All rights reserved.
  5. *
  6. * This Source Code Form is subject to the terms of the MIT
  7. * License, If a copy of the MIT License was not distributed with this
  8. * file, You can obtain one at https://opensource.org/licenses/MIT.
  9. */
  10. package engine
  11. import (
  12. "sort"
  13. "strings"
  14. )
  15. // Globals
  16. // =======
  17. /*
  18. RuleKindSeparator is the separator for rule kinds
  19. */
  20. const RuleKindSeparator = "."
  21. /*
  22. RuleKindWildcard is a wildcard for rule kinds
  23. */
  24. const RuleKindWildcard = "*"
  25. // Messages
  26. // ========
  27. /*
  28. MessageRootMonitorFinished is send from a root monitor when it has finished
  29. */
  30. const MessageRootMonitorFinished = "MessageRootMonitorFinished"
  31. // Rule Scope
  32. // ==========
  33. /*
  34. RuleScope is a set of scope definitions for rules. Each definition allows or disallows
  35. a set of rule types. Scope definitions and rule sets are usually expressed with
  36. named paths (scope paths) in dot notation (e.g. core.data.read).
  37. */
  38. type RuleScope struct {
  39. scopeDefs map[string]interface{}
  40. }
  41. const ruleScopeAllowFlag = "."
  42. /*
  43. NewRuleScope creates a new rule scope object with an initial set of definitions.
  44. */
  45. func NewRuleScope(allows map[string]bool) *RuleScope {
  46. rs := &RuleScope{make(map[string]interface{})}
  47. rs.AddAll(allows)
  48. return rs
  49. }
  50. /*
  51. IsAllowedAll checks if all given scopes are allowed.
  52. */
  53. func (rs *RuleScope) IsAllowedAll(scopePaths []string) bool {
  54. for _, path := range scopePaths {
  55. if !rs.IsAllowed(path) {
  56. return false
  57. }
  58. }
  59. return true
  60. }
  61. /*
  62. IsAllowed checks if a given scope path is allowed within this rule scope.
  63. */
  64. func (rs *RuleScope) IsAllowed(scopePath string) bool {
  65. allowed := false
  66. scopeDefs := rs.scopeDefs
  67. if a, ok := scopeDefs[ruleScopeAllowFlag]; ok {
  68. allowed = a.(bool)
  69. }
  70. for _, scopeStep := range strings.Split(scopePath, ".") {
  71. val, ok := scopeDefs[scopeStep]
  72. if !ok {
  73. break
  74. }
  75. scopeDefs = val.(map[string]interface{})
  76. if a, ok := scopeDefs[ruleScopeAllowFlag]; ok {
  77. allowed = a.(bool)
  78. }
  79. }
  80. return allowed
  81. }
  82. /*
  83. AddAll adds all given definitions to the rule scope.
  84. */
  85. func (rs *RuleScope) AddAll(allows map[string]bool) {
  86. for scopePath, allow := range allows {
  87. rs.Add(scopePath, allow)
  88. }
  89. }
  90. /*
  91. Add adds a given definition to the rule scope.
  92. */
  93. func (rs *RuleScope) Add(scopePath string, allow bool) {
  94. scopeDefs := rs.scopeDefs
  95. if scopePath != "" {
  96. for _, scopeStep := range strings.Split(scopePath, ".") {
  97. val, ok := scopeDefs[scopeStep]
  98. if !ok {
  99. val = make(map[string]interface{})
  100. scopeDefs[scopeStep] = val
  101. }
  102. scopeDefs = val.(map[string]interface{})
  103. }
  104. }
  105. scopeDefs[ruleScopeAllowFlag] = allow
  106. }
  107. // Rule sorting
  108. // ============
  109. /*
  110. RuleSlice is a slice of rules
  111. */
  112. type RuleSlice []*Rule
  113. func (s RuleSlice) Len() int { return len(s) }
  114. func (s RuleSlice) Less(i, j int) bool { return s[i].Priority < s[j].Priority }
  115. func (s RuleSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
  116. /*
  117. SortRuleSlice sorts a slice of rules.
  118. */
  119. func SortRuleSlice(a []*Rule) { sort.Sort(RuleSlice(a)) }
  120. // Unit testing
  121. // ============
  122. /*
  123. UnitTestResetIDs reset all counting IDs.
  124. THIS FUNCTION SHOULD ONLY BE CALLED BY UNIT TESTS!
  125. */
  126. func UnitTestResetIDs() {
  127. pidcounter = 1
  128. ruleindexidcounter = 1
  129. midcounter = 1
  130. }