waylon-core 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.roxanne.yml +4 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +38 -0
  6. data/.ruby-version +1 -0
  7. data/CHANGELOG.md +5 -0
  8. data/Gemfile +6 -0
  9. data/Gemfile.lock +137 -0
  10. data/LICENSE.txt +21 -0
  11. data/README.md +57 -0
  12. data/Rakefile +23 -0
  13. data/bin/console +17 -0
  14. data/bin/setup +8 -0
  15. data/lib/waylon/base_component.rb +124 -0
  16. data/lib/waylon/condition.rb +64 -0
  17. data/lib/waylon/conditions/default.rb +34 -0
  18. data/lib/waylon/conditions/permission_denied.rb +34 -0
  19. data/lib/waylon/conditions/regex.rb +22 -0
  20. data/lib/waylon/config.rb +134 -0
  21. data/lib/waylon/core.rb +46 -0
  22. data/lib/waylon/exceptions/not_implemented_error.rb +9 -0
  23. data/lib/waylon/exceptions/validation_error.rb +9 -0
  24. data/lib/waylon/generic_exception.rb +7 -0
  25. data/lib/waylon/group.rb +70 -0
  26. data/lib/waylon/logger.rb +41 -0
  27. data/lib/waylon/message.rb +17 -0
  28. data/lib/waylon/route.rb +71 -0
  29. data/lib/waylon/routes/default.rb +17 -0
  30. data/lib/waylon/routes/permission_denied.rb +17 -0
  31. data/lib/waylon/rspec/matchers/route_matcher.rb +43 -0
  32. data/lib/waylon/rspec/skill.rb +71 -0
  33. data/lib/waylon/rspec/test_channel.rb +83 -0
  34. data/lib/waylon/rspec/test_message.rb +63 -0
  35. data/lib/waylon/rspec/test_sense.rb +110 -0
  36. data/lib/waylon/rspec/test_server.rb +120 -0
  37. data/lib/waylon/rspec/test_user.rb +165 -0
  38. data/lib/waylon/rspec/test_worker.rb +15 -0
  39. data/lib/waylon/rspec.rb +50 -0
  40. data/lib/waylon/sense.rb +74 -0
  41. data/lib/waylon/sense_registry.rb +30 -0
  42. data/lib/waylon/skill.rb +132 -0
  43. data/lib/waylon/skill_registry.rb +74 -0
  44. data/lib/waylon/skills/default.rb +48 -0
  45. data/lib/waylon/skills/fun.rb +26 -0
  46. data/lib/waylon/user.rb +61 -0
  47. data/lib/waylon/version.rb +12 -0
  48. data/lib/waylon/webhook.rb +73 -0
  49. data/lib/waylon.rb +5 -0
  50. data/scripts/test.sh +5 -0
  51. data/waylon-core.gemspec +50 -0
  52. metadata +312 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 01c6d89ed4d79dba9305c9c83fd597fed10ace104592f7d8ae6ed2f630bb9351
4
+ data.tar.gz: 83ac891dc983e61f76b5cd366062381b748dcc49c86d6177b4e245c8c29573e0
5
+ SHA512:
6
+ metadata.gz: bd0fabfda6646c84cb17af27dd55bd8c70ad1c803a257e1e4ed992ce4298563a579705dff33b898519b82ed2123e59ab2259021bbdec320914914a7ee19291f0
7
+ data.tar.gz: 5b2c06fc2c55256014f35e953465f21c11c6de9390e55c0a504f7fcb08c2fcff1898e583dac97b546b1d1a7c00650014562c2e678aff6832353a3c24f08527b8
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+
10
+ # rspec failure tracking
11
+ .rspec_status
data/.roxanne.yml ADDED
@@ -0,0 +1,4 @@
1
+ version: 1.0
2
+ stages:
3
+ test:
4
+ image: ruby:3.0
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,38 @@
1
+ AllCops:
2
+ TargetRubyVersion: 3.0
3
+ NewCops: enable
4
+
5
+ Style/MixinUsage:
6
+ Exclude:
7
+ - "bin/console"
8
+
9
+ Style/StringLiterals:
10
+ Enabled: true
11
+ EnforcedStyle: double_quotes
12
+
13
+ Style/StringLiteralsInInterpolation:
14
+ Enabled: true
15
+ EnforcedStyle: double_quotes
16
+
17
+ Layout/LineLength:
18
+ Max: 120
19
+
20
+ Gemspec/RequireMFA:
21
+ Enabled: false
22
+
23
+ Metrics/AbcSize:
24
+ Max: 19
25
+
26
+ Metrics/CyclomaticComplexity:
27
+ Max: 9
28
+
29
+ Metrics/PerceivedComplexity:
30
+ Max: 9
31
+
32
+ Metrics/MethodLength:
33
+ Max: 20
34
+
35
+ Metrics/BlockLength:
36
+ Exclude:
37
+ - "**/*_spec.rb"
38
+ - "*.gemspec"
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.0.3
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2021-11-17
4
+
5
+ - Initial release
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in waylon-core.gemspec
6
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,137 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ waylon-core (0.1.0)
5
+ addressable (~> 2.8)
6
+ faraday (~> 1.8)
7
+ i18n (~> 1.8)
8
+ json (~> 2.6)
9
+ moneta (~> 1.4)
10
+ puma (~> 5.5)
11
+ resque (~> 2.2)
12
+
13
+ GEM
14
+ remote: https://rubygems.org/
15
+ specs:
16
+ addressable (2.8.0)
17
+ public_suffix (>= 2.0.2, < 5.0)
18
+ ast (2.4.2)
19
+ concurrent-ruby (1.1.9)
20
+ diff-lcs (1.4.4)
21
+ docile (1.4.0)
22
+ faraday (1.8.0)
23
+ faraday-em_http (~> 1.0)
24
+ faraday-em_synchrony (~> 1.0)
25
+ faraday-excon (~> 1.1)
26
+ faraday-httpclient (~> 1.0.1)
27
+ faraday-net_http (~> 1.0)
28
+ faraday-net_http_persistent (~> 1.1)
29
+ faraday-patron (~> 1.0)
30
+ faraday-rack (~> 1.0)
31
+ multipart-post (>= 1.2, < 3)
32
+ ruby2_keywords (>= 0.0.4)
33
+ faraday-em_http (1.0.0)
34
+ faraday-em_synchrony (1.0.0)
35
+ faraday-excon (1.1.0)
36
+ faraday-httpclient (1.0.1)
37
+ faraday-net_http (1.0.1)
38
+ faraday-net_http_persistent (1.2.0)
39
+ faraday-patron (1.0.0)
40
+ faraday-rack (1.0.0)
41
+ i18n (1.8.11)
42
+ concurrent-ruby (~> 1.0)
43
+ json (2.6.1)
44
+ moneta (1.4.2)
45
+ mono_logger (1.1.1)
46
+ multi_json (1.15.0)
47
+ multipart-post (2.1.1)
48
+ mustermann (1.1.1)
49
+ ruby2_keywords (~> 0.0.1)
50
+ nio4r (2.5.8)
51
+ parallel (1.21.0)
52
+ parser (3.0.3.2)
53
+ ast (~> 2.4.1)
54
+ public_suffix (4.0.6)
55
+ puma (5.5.2)
56
+ nio4r (~> 2.0)
57
+ rack (2.2.3)
58
+ rack-protection (2.1.0)
59
+ rack
60
+ rainbow (3.0.0)
61
+ rake (13.0.6)
62
+ redis (4.5.1)
63
+ redis-namespace (1.8.1)
64
+ redis (>= 3.0.4)
65
+ regexp_parser (2.2.0)
66
+ resque (2.2.0)
67
+ mono_logger (~> 1.0)
68
+ multi_json (~> 1.0)
69
+ redis-namespace (~> 1.6)
70
+ sinatra (>= 0.9.2)
71
+ vegas (~> 0.1.2)
72
+ rexml (3.2.5)
73
+ rspec (3.10.0)
74
+ rspec-core (~> 3.10.0)
75
+ rspec-expectations (~> 3.10.0)
76
+ rspec-mocks (~> 3.10.0)
77
+ rspec-core (3.10.1)
78
+ rspec-support (~> 3.10.0)
79
+ rspec-expectations (3.10.1)
80
+ diff-lcs (>= 1.2.0, < 2.0)
81
+ rspec-support (~> 3.10.0)
82
+ rspec-mocks (3.10.2)
83
+ diff-lcs (>= 1.2.0, < 2.0)
84
+ rspec-support (~> 3.10.0)
85
+ rspec-support (3.10.3)
86
+ rubocop (1.23.0)
87
+ parallel (~> 1.10)
88
+ parser (>= 3.0.0.0)
89
+ rainbow (>= 2.2.2, < 4.0)
90
+ regexp_parser (>= 1.8, < 3.0)
91
+ rexml
92
+ rubocop-ast (>= 1.12.0, < 2.0)
93
+ ruby-progressbar (~> 1.7)
94
+ unicode-display_width (>= 1.4.0, < 3.0)
95
+ rubocop-ast (1.15.0)
96
+ parser (>= 3.0.1.1)
97
+ rubocop-rake (0.6.0)
98
+ rubocop (~> 1.0)
99
+ rubocop-rspec (2.6.0)
100
+ rubocop (~> 1.19)
101
+ ruby-progressbar (1.11.0)
102
+ ruby2_keywords (0.0.5)
103
+ simplecov (0.21.2)
104
+ docile (~> 1.1)
105
+ simplecov-html (~> 0.11)
106
+ simplecov_json_formatter (~> 0.1)
107
+ simplecov-html (0.12.3)
108
+ simplecov_json_formatter (0.1.3)
109
+ sinatra (2.1.0)
110
+ mustermann (~> 1.0)
111
+ rack (~> 2.2)
112
+ rack-protection (= 2.1.0)
113
+ tilt (~> 2.0)
114
+ tilt (2.0.10)
115
+ unicode-display_width (2.1.0)
116
+ vegas (0.1.11)
117
+ rack (>= 1.0.0)
118
+ webrick (1.7.0)
119
+ yard (0.9.27)
120
+ webrick (~> 1.7.0)
121
+
122
+ PLATFORMS
123
+ arm64-darwin-21
124
+
125
+ DEPENDENCIES
126
+ bundler (~> 2.2)
127
+ rake (~> 13.0)
128
+ rspec (~> 3.10)
129
+ rubocop (~> 1.23)
130
+ rubocop-rake (~> 0.6)
131
+ rubocop-rspec (~> 2.6)
132
+ simplecov (~> 0.21)
133
+ waylon-core!
134
+ yard (~> 0.9, >= 0.9.27)
135
+
136
+ BUNDLED WITH
137
+ 2.2.32
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Jonathan Gnagy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,57 @@
1
+ # Waylon::Core
2
+
3
+ Waylon is a bot framework in the same vein as [Lita](https://www.lita.io/) built to make creating bots easy and fun. It supports swappable sensory inputs (chat platforms, web endpoints, and more), easy to build Skills, built-in and extensible permissions, and modern JSON logging.
4
+
5
+ This repo/library is the core of Waylon; it provides the essential pieces of the framework and some working examples.
6
+
7
+ ## Why Waylon
8
+
9
+ Waylon is built to be scalable and to deliver features missing in other chat frameworks. For instance, it supports self-reporting and discovering plugin features (such as supporting HTML cards, reactions, etc.) to making Skills more powerful and dynamic. Waylon also supports a full, shared caching layer to make scaling simple. It also makes heavy use of Redis for queuing work, meaning zero-downtime upgrades and faster user responses.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'waylon-core'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle install
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install waylon-core
26
+
27
+ If you're building a plugin for Waylon, you'll only need to require the core:
28
+
29
+ ```ruby
30
+ require "waylon/core"
31
+ ```
32
+
33
+ If you're launching your own bot, require the entire library and plus any additional plugins:
34
+
35
+ ```ruby
36
+ require "waylon"
37
+ ```
38
+
39
+ ## Usage
40
+
41
+ ### Demo Mode
42
+
43
+ Alone, this library isn't super useful for running a bot, but it does include a "demo", local REPL mode for experimenting. To use it, run `rake demo`.
44
+
45
+ ## Development
46
+
47
+ Waylon's development pipeline makes heavy use of [RSpec](https://rspec.info/) for testing (and [SimpleCov](https://github.com/simplecov-ruby/simplecov) for reporting on coverage), [Rubocop](https://rubocop.org/) for linting/format checking, [YARD](https://yardoc.org/) for documentation, and [Travis CI](https://www.travis-ci.com/) for CI. Most of this is built-in and will work out-of-the-box for GitHub PRs.
48
+
49
+ To get started locally, after checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake` to run the tests and linting. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
50
+
51
+ ## Contributing
52
+
53
+ Bug reports and pull requests are welcome on GitHub at https://github.com/jgnagy/waylon-core.
54
+
55
+ ## License
56
+
57
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
6
+ require "redis/errors"
7
+ require "resque/tasks"
8
+ require "yard"
9
+ require "waylon/core"
10
+
11
+ RSpec::Core::RakeTask.new(:spec)
12
+ RuboCop::RakeTask.new
13
+ YARD::Rake::YardocTask.new do |y|
14
+ y.options = [
15
+ "--markup", "markdown"
16
+ ]
17
+ end
18
+
19
+ task default: %i[spec rubocop yard]
20
+
21
+ task :demo do
22
+ require "waylon/rspec/test_server"
23
+ end
data/bin/console ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "waylon"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require "irb"
15
+ include Waylon
16
+
17
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,124 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Waylon
4
+ # The base mixin for all core Waylon components
5
+ # @abstract
6
+ module BaseComponent
7
+ def self.included(base)
8
+ base.send :include, InstanceLoggingMethods
9
+ base.send :include, InstanceUtilityMethods
10
+ base.extend ClassLoggingMethods
11
+ base.extend ClassUtilityMethods
12
+ end
13
+
14
+ # Base class logging methods
15
+ module ClassLoggingMethods
16
+ # Simple pass-through for logging through the Waylon Logger
17
+ # @param message [String] The message to log
18
+ # @param level [String,Symbol] The log level for this message
19
+ def log(message, level = :info)
20
+ ::Waylon::Logger.log(message, level)
21
+ end
22
+ end
23
+
24
+ # Base Component utility methods
25
+ module ClassUtilityMethods
26
+ # The namespace used for this component's storage
27
+ # @param value [String,nil] Sets this namespace unless set (without setting, returns a sane default)
28
+ # @return [String] The namespace for this component
29
+ def component_namespace(value = nil)
30
+ @namespace ||= value
31
+ # Either returns the namespace or the stripped down class name
32
+ @namespace || name.to_s.split("::").last.downcase
33
+ end
34
+
35
+ # Creates namespaced configuration keys for Webhook subclasses
36
+ # @param (see Config#add_schema)
37
+ def config(key, default: nil, required: false, type: String)
38
+ conf = Config.instance
39
+ config_key = config_key_for(key)
40
+ conf.add_schema(config_key, default: default, required: required, type: type)
41
+ end
42
+
43
+ # Provides the full Config key given a relative key
44
+ # @param key [String] The relative key to fully-qualify
45
+ # @return [String] The fully-qualified Config key
46
+ def config_key_for(key)
47
+ "#{config_namespace}.#{key}"
48
+ end
49
+
50
+ # Determines if the current component is fully configured
51
+ # @return [Boolean]
52
+ def configured?
53
+ conf = Config.instance
54
+ req_confs = conf.schema.select do |k, v|
55
+ k.match?(/^#{config_namespace}\./) && v[:required]
56
+ end
57
+ missing_configs = req_confs.reject { |k, _v| conf.set?(k) }
58
+ if missing_configs.empty? && conf.valid?
59
+ true
60
+ elsif missing_configs.empty?
61
+ log("Configuration for #{component_namespace} failed validation!", :error)
62
+ false
63
+ else
64
+ missing_configs.each { |k, _v| log("Missing required configuration: #{k}", :error) }
65
+ false
66
+ end
67
+ end
68
+
69
+ # Describes features supported by a Sense
70
+ # @param list [String,Array<String,Symbol>] List of features supported by this BaseComponent
71
+ def features(list)
72
+ @features = [*list].map(&:to_sym)
73
+ end
74
+
75
+ # Determine if a BaseComponent subclass supports a feature
76
+ # @param key [String,Symbol] The feature in question
77
+ def supports?(key)
78
+ @features ||= []
79
+ @features.include?(key.to_sym)
80
+ end
81
+ end
82
+
83
+ # Base instance logging methods
84
+ module InstanceLoggingMethods
85
+ # Instance-level access to logging via the Class log method
86
+ # @param (see ClassLoggingMethods#log)
87
+ def log(message, level = :info)
88
+ self.class.log(message, level)
89
+ end
90
+ end
91
+
92
+ # Base instance utility methods
93
+ module InstanceUtilityMethods
94
+ # Allows caching operations (or retrieving cached versions)
95
+ # @param [String] key How to store/retrieved the cached value
96
+ # @param [Integer] expires How long to cache the value
97
+ def cache(key, expires: 600)
98
+ cache_key = self.class.config_key_for(key)
99
+ if !Waylon::Cache.key?(cache_key) && block_given?
100
+ result = yield
101
+ Waylon::Cache.store(cache_key, result, expires: expires)
102
+ elsif !Waylon::Cache.key?(cache_key)
103
+ return nil
104
+ end
105
+ Waylon::Cache.load(cache_key, expires: expires)
106
+ end
107
+
108
+ # A wrapper for access to a namespaced Config key
109
+ # @param [String] key The key name to lookup
110
+ def config(key)
111
+ conf = Config.instance
112
+ conf[self.class.config_key_for(key)]
113
+ end
114
+
115
+ # A wrapper for accessing the persistent storage
116
+ # @return [Waylon::Storage] The Storage wrapper class
117
+ def storage
118
+ Waylon::Storage
119
+ end
120
+
121
+ alias db storage
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Waylon
4
+ # Abstract route condition superclass
5
+ # @abstract
6
+ class Condition
7
+ attr_reader :action, :help, :mechanism
8
+
9
+ # @param mechanism The meat of the condition used to decide if this condition applies
10
+ # @param action [Symbol] The method to call if the condition matches
11
+ # @param allowed_groups [Array<Symbol>] The group names allowed to use this action
12
+ # @param help [String] Optional help text to describe usage for this action
13
+ def initialize(mechanism, action, allowed_groups, help = nil)
14
+ @mechanism = mechanism
15
+ @action = action
16
+ @allowed_groups = allowed_groups
17
+ @help = help
18
+ end
19
+
20
+ # Placeholder for determining if this condition applies to the given input
21
+ # @param _input [Waylon::Message] The input message
22
+ def matches?(_input)
23
+ false
24
+ end
25
+
26
+ # Checks if a user is allowed based on this condition
27
+ # @param user [Waylon::User] abstract user
28
+ def permits?(user)
29
+ return true if allows?(:everyone)
30
+
31
+ Logger.log("Checking permissions for #{user.email}", :debug)
32
+ group_class = user.class.sense.group_class
33
+ # Check for global admins
34
+ return true if Config.instance.admins.include?(user.email)
35
+ # Check for managed admins
36
+ return true if group_class.new("admins").include?(user)
37
+
38
+ permitted = false
39
+
40
+ [*@allowed_groups].each do |group|
41
+ permitted = true if group_class.new(group).include?(user)
42
+ break if permitted
43
+ end
44
+ permitted
45
+ end
46
+
47
+ # Tokens is used to provide details about the message input to the action
48
+ # @param _input [String] The message content as text
49
+ # @return [Array<String>] The tokens extracted from the input message
50
+ def tokens(_input)
51
+ []
52
+ end
53
+
54
+ private
55
+
56
+ # Determines if a group name is among the list of allowed groups for this condition
57
+ # @note Does not involve determining user group membership, just allows access to the list of allowed groups
58
+ # @param group [Symbol] A group name to lookup
59
+ def allows?(group)
60
+ @allowed_groups ||= []
61
+ [*@allowed_groups].include?(group.to_sym)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Waylon
4
+ module Conditions
5
+ # A pre-made catch-all condition for denying access
6
+ class Default < Condition
7
+ # Overrides normal Condition initialization to force a specific action
8
+ def initialize(*_args) # rubocop:disable Lint/MissingSuper
9
+ @mechanism = nil
10
+ @action = :unknown
11
+ @allowed_groups = [:everyone]
12
+ @help = ""
13
+ end
14
+
15
+ # Matches any input (since the Default route, when used, should always function)
16
+ # @return [Boolean]
17
+ def matches?(_input)
18
+ true
19
+ end
20
+
21
+ # Permits any user (since the Default route, when used, should always function)
22
+ # @return [Boolean]
23
+ def permits?(_user)
24
+ true
25
+ end
26
+
27
+ # Just provides back all input as a single token
28
+ # @return [Array<String>]
29
+ def tokens(input)
30
+ [input]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Waylon
4
+ module Conditions
5
+ # A pre-made catch-all condition for denying access
6
+ class PermissionDenied < Condition
7
+ # Overrides normal Condition initialization to force a specific action
8
+ def initialize(*_args) # rubocop:disable Lint/MissingSuper
9
+ @mechanism = nil
10
+ @action = :denied
11
+ @allowed_groups = [:everyone]
12
+ @help = "This action is not allowed"
13
+ end
14
+
15
+ # Matches any input (since the PermissionDenied route, when used, should always function)
16
+ # @return [Boolean]
17
+ def matches?(_input)
18
+ true
19
+ end
20
+
21
+ # Permits any user (since the PermissionDenied route, when used, should always function)
22
+ # @return [Boolean]
23
+ def permits?(_user)
24
+ true
25
+ end
26
+
27
+ # Just provides back all input as a single token
28
+ # @return [Array<String>]
29
+ def tokens(input)
30
+ [input]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Waylon
4
+ module Conditions
5
+ # Routing via Regular Expression
6
+ class Regex < Condition
7
+ # Checks if this condition matches the message
8
+ # @param message [String] The message text
9
+ # @return [Boolean]
10
+ def matches?(message)
11
+ @mechanism =~ message
12
+ end
13
+
14
+ # Provides the regular expression match groups as tokens
15
+ # @param input [String] The message text
16
+ # @return [Array<String>] The regular expression match groups
17
+ def tokens(input)
18
+ @mechanism.match(input).to_a[1..]
19
+ end
20
+ end
21
+ end
22
+ end