newshound 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rspec +3 -0
- data/.tool-versions +1 -0
- data/Gemfile +9 -3
- data/README.md +154 -75
- data/TRANSPORT_USAGE.md +117 -0
- data/lib/generators/newshound/install/install_generator.rb +40 -0
- data/lib/generators/newshound/install/templates/newshound.rb +32 -0
- data/lib/newshound/authorization.rb +46 -0
- data/lib/newshound/configuration.rb +12 -11
- data/lib/newshound/exception_reporter.rb +18 -8
- data/lib/newshound/middleware/banner_injector.rb +288 -0
- data/lib/newshound/que_reporter.rb +20 -10
- data/lib/newshound/railtie.rb +32 -36
- data/lib/newshound/version.rb +1 -1
- data/lib/newshound.rb +5 -43
- data/newshound.gemspec +34 -0
- metadata +12 -105
- data/lib/newshound/daily_report_job.rb +0 -19
- data/lib/newshound/scheduler.rb +0 -41
- data/lib/newshound/slack_notifier.rb +0 -61
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ed2c9eae65ac8681fc1c72890cbd421ca9dd73130c37fa86c04643cb74c03856
|
|
4
|
+
data.tar.gz: 7ccb875f08607e1478245384376a621243fdd44e40443fb191064210cff94ba6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a78bd31f883c89116c83b7c77b680faba172b41e0bc3f375e4a81a075503d33860ebd4778e71f11d868a794fe04effd815e240ebd3d5c6135b0ed80599c87469
|
|
7
|
+
data.tar.gz: 4985d3d128688284f4734391b12e7f6e34d1c69857d713d3995d2078cc4df210b64ca5f84d889841e52b1b3a9086bcf0f19e7d35bef646b60e08020379527ad6
|
data/.rspec
ADDED
data/.tool-versions
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ruby 3.4.3
|
data/Gemfile
CHANGED
|
@@ -4,6 +4,12 @@ source "https://rubygems.org"
|
|
|
4
4
|
|
|
5
5
|
gemspec
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
gem "
|
|
9
|
-
gem "
|
|
7
|
+
group :development, :test do
|
|
8
|
+
gem "bundler", "~> 2.0"
|
|
9
|
+
gem "rake", "~> 13.0"
|
|
10
|
+
gem "rspec", "~> 3.0"
|
|
11
|
+
gem "rubocop", "~> 1.0"
|
|
12
|
+
gem "pg"
|
|
13
|
+
gem "pry"
|
|
14
|
+
gem "simplecov", require: false
|
|
15
|
+
end
|
data/README.md
CHANGED
|
@@ -1,115 +1,192 @@
|
|
|
1
1
|
# Newshound 🐕
|
|
2
2
|
|
|
3
|
-
A Ruby gem that
|
|
3
|
+
A Ruby gem that displays real-time exceptions and job statuses in a collapsible banner for authorized users in your Rails application.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
7
|
+
- 🎯 **Real-time Web UI Banner** - Shows exceptions and job statuses at the top of every page
|
|
8
|
+
- 🔐 **Role-Based Access** - Only visible to authorized users (developers, admins, etc.)
|
|
9
|
+
- 📊 **Que Job Monitoring** - Real-time queue health and job status
|
|
10
|
+
- 🚨 **Exception Tracking** - Recent exceptions from exception-track
|
|
11
|
+
- 🎨 **Collapsible UI** - Clean, non-intrusive banner that expands on click
|
|
12
|
+
- ⚡ **Zero Configuration** - Automatically injects into HTML responses
|
|
13
|
+
- 🔧 **Highly Customizable** - Configure roles and authorization logic
|
|
12
14
|
|
|
13
15
|
## Installation
|
|
14
16
|
|
|
15
17
|
Add to your Gemfile:
|
|
16
18
|
|
|
17
19
|
```ruby
|
|
18
|
-
gem 'newshound'
|
|
20
|
+
gem 'newshound'
|
|
19
21
|
```
|
|
20
22
|
|
|
21
23
|
Then:
|
|
22
24
|
|
|
23
25
|
```bash
|
|
24
26
|
bundle install
|
|
27
|
+
rails generate newshound:install
|
|
25
28
|
```
|
|
26
29
|
|
|
30
|
+
The generator will create `config/initializers/newshound.rb` with default configuration.
|
|
31
|
+
|
|
27
32
|
## Configuration
|
|
28
33
|
|
|
29
|
-
|
|
34
|
+
### Basic Configuration
|
|
30
35
|
|
|
31
36
|
```ruby
|
|
37
|
+
# config/initializers/newshound.rb
|
|
32
38
|
Newshound.configure do |config|
|
|
33
|
-
#
|
|
34
|
-
config.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
config.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
config.
|
|
41
|
-
|
|
39
|
+
# Enable or disable the banner
|
|
40
|
+
config.enabled = true
|
|
41
|
+
|
|
42
|
+
# Maximum number of exceptions to show in banner
|
|
43
|
+
config.exception_limit = 10
|
|
44
|
+
|
|
45
|
+
# User roles that can view the banner
|
|
46
|
+
config.authorized_roles = [:developer, :super_user]
|
|
47
|
+
|
|
48
|
+
# Method to call to get current user (most apps use :current_user)
|
|
49
|
+
config.current_user_method = :current_user
|
|
50
|
+
end
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Advanced: Custom Authorization
|
|
54
|
+
|
|
55
|
+
If the default role-based authorization doesn't fit your needs, you can provide custom logic:
|
|
56
|
+
|
|
57
|
+
```ruby
|
|
58
|
+
# config/initializers/newshound.rb
|
|
59
|
+
Newshound.authorize_with do |controller|
|
|
60
|
+
# Your custom authorization logic
|
|
61
|
+
# Return true to show banner, false to hide
|
|
62
|
+
user = controller.current_user
|
|
63
|
+
user&.admin? || user&.developer?
|
|
64
|
+
end
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Example Authorization Scenarios
|
|
68
|
+
|
|
69
|
+
```ruby
|
|
70
|
+
# Only show in development
|
|
71
|
+
Newshound.authorize_with do |controller|
|
|
72
|
+
Rails.env.development?
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Check multiple conditions
|
|
76
|
+
Newshound.authorize_with do |controller|
|
|
77
|
+
user = controller.current_user
|
|
78
|
+
user.present? &&
|
|
79
|
+
(user.has_role?(:admin) || user.email.ends_with?('@yourcompany.com'))
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Use your existing authorization system
|
|
83
|
+
Newshound.authorize_with do |controller|
|
|
84
|
+
controller.current_user&.can?(:view_newshound)
|
|
42
85
|
end
|
|
43
86
|
```
|
|
44
87
|
|
|
45
|
-
|
|
88
|
+
## How It Works
|
|
89
|
+
|
|
90
|
+
Newshound uses Rails middleware to automatically inject a banner into HTML responses for authorized users. The banner:
|
|
91
|
+
|
|
92
|
+
1. ✅ Appears automatically on all HTML pages
|
|
93
|
+
2. 🔒 Only visible to users with authorized roles
|
|
94
|
+
3. 📊 Shows real-time data from your exception and job queues
|
|
95
|
+
4. 🎨 Collapses to save space, expands on click
|
|
96
|
+
5. 🚀 No JavaScript dependencies, pure CSS animations
|
|
46
97
|
|
|
47
|
-
|
|
48
|
-
1. Go to https://api.slack.com/apps
|
|
49
|
-
2. Create a new app or select existing
|
|
50
|
-
3. Enable "Incoming Webhooks"
|
|
51
|
-
4. Add a new webhook for your channel
|
|
52
|
-
5. Copy the webhook URL to your config
|
|
98
|
+
## Banner Content
|
|
53
99
|
|
|
54
|
-
|
|
55
|
-
1. Create a Slack app at https://api.slack.com/apps
|
|
56
|
-
2. Add OAuth scopes: `chat:write`, `chat:write.public`
|
|
57
|
-
3. Install to workspace
|
|
58
|
-
4. Copy the Bot User OAuth Token
|
|
59
|
-
5. Set as `ENV['SLACK_API_TOKEN']`
|
|
100
|
+
The banner displays:
|
|
60
101
|
|
|
61
|
-
|
|
102
|
+
### Exception Section
|
|
103
|
+
- Recent exceptions from exception-track
|
|
104
|
+
- Exception class and message
|
|
105
|
+
- Controller/action where it occurred
|
|
106
|
+
- Timestamp
|
|
107
|
+
- Visual indicators (🟢 all clear / 🔴 errors)
|
|
62
108
|
|
|
63
|
-
###
|
|
109
|
+
### Job Queue Section
|
|
110
|
+
- **Ready to Run**: Jobs waiting to execute
|
|
111
|
+
- **Scheduled**: Jobs scheduled for future execution
|
|
112
|
+
- **Failed**: Jobs in retry queue
|
|
113
|
+
- **Completed Today**: Successfully finished jobs
|
|
114
|
+
- Color-coded health status
|
|
64
115
|
|
|
65
|
-
|
|
116
|
+
## User Requirements
|
|
66
117
|
|
|
67
|
-
|
|
118
|
+
Your User model should have a `role` attribute that matches one of the configured `authorized_roles`. Common patterns:
|
|
68
119
|
|
|
69
120
|
```ruby
|
|
70
|
-
#
|
|
71
|
-
|
|
121
|
+
# String enum
|
|
122
|
+
class User < ApplicationRecord
|
|
123
|
+
enum role: { user: 'user', developer: 'developer', admin: 'admin' }
|
|
124
|
+
end
|
|
72
125
|
|
|
73
|
-
#
|
|
74
|
-
|
|
126
|
+
# Symbol enum
|
|
127
|
+
class User < ApplicationRecord
|
|
128
|
+
enum role: { user: 0, developer: 1, super_user: 2 }
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# String column
|
|
132
|
+
class User < ApplicationRecord
|
|
133
|
+
def role
|
|
134
|
+
@role ||= read_attribute(:role)&.to_sym
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
If your User model uses different attribute names, you can customize the authorization logic using `Newshound.authorize_with`.
|
|
140
|
+
|
|
141
|
+
## Testing
|
|
75
142
|
|
|
76
|
-
|
|
77
|
-
rake newshound:schedule
|
|
143
|
+
### Test Reporters
|
|
78
144
|
|
|
79
|
-
|
|
145
|
+
```bash
|
|
146
|
+
# Test exception reporter
|
|
147
|
+
rake newshound:test_exceptions
|
|
148
|
+
|
|
149
|
+
# Test job queue reporter
|
|
150
|
+
rake newshound:test_jobs
|
|
151
|
+
|
|
152
|
+
# Show current configuration
|
|
80
153
|
rake newshound:config
|
|
81
154
|
```
|
|
82
155
|
|
|
83
|
-
###
|
|
156
|
+
### Test in Rails Console
|
|
84
157
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
158
|
+
```ruby
|
|
159
|
+
# Check if banner would show for a specific user
|
|
160
|
+
user = User.find(123)
|
|
161
|
+
controller = ApplicationController.new
|
|
162
|
+
controller.instance_variable_set(:@current_user, user)
|
|
163
|
+
Newshound::Authorization.authorized?(controller)
|
|
164
|
+
# => true or false
|
|
92
165
|
```
|
|
93
166
|
|
|
94
|
-
|
|
167
|
+
## Troubleshooting
|
|
95
168
|
|
|
96
|
-
|
|
169
|
+
### Banner not appearing
|
|
97
170
|
|
|
98
|
-
|
|
171
|
+
1. **Check if enabled**: `rake newshound:config`
|
|
172
|
+
2. **Verify user role**: Make sure your user has an authorized role
|
|
173
|
+
3. **Check current_user method**: Ensure your app provides the configured method
|
|
174
|
+
4. **Restart server**: Changes to initializers require a restart
|
|
99
175
|
|
|
100
|
-
###
|
|
101
|
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
104
|
-
|
|
176
|
+
### No exceptions showing
|
|
177
|
+
|
|
178
|
+
- Ensure `exception-track` gem is installed and logging exceptions
|
|
179
|
+
- Check that exceptions exist: `rake newshound:test_exceptions`
|
|
180
|
+
|
|
181
|
+
### No job data
|
|
182
|
+
|
|
183
|
+
- Verify Que is configured and `que_jobs` table exists
|
|
184
|
+
- Check job data: `rake newshound:test_jobs`
|
|
185
|
+
|
|
186
|
+
### Banner appears for wrong users
|
|
105
187
|
|
|
106
|
-
|
|
107
|
-
-
|
|
108
|
-
- Queue health status
|
|
109
|
-
- Ready to run count
|
|
110
|
-
- Scheduled jobs count
|
|
111
|
-
- Failed jobs in retry queue
|
|
112
|
-
- Jobs completed today
|
|
188
|
+
- Review `authorized_roles` configuration
|
|
189
|
+
- Consider using custom authorization with `Newshound.authorize_with`
|
|
113
190
|
|
|
114
191
|
## Development
|
|
115
192
|
|
|
@@ -124,20 +201,22 @@ bundle exec rubocop
|
|
|
124
201
|
bin/console
|
|
125
202
|
```
|
|
126
203
|
|
|
127
|
-
##
|
|
204
|
+
## Dependencies
|
|
128
205
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
Newshound.report! # Should post to Slack immediately
|
|
133
|
-
```
|
|
206
|
+
- **Rails** >= 6.0
|
|
207
|
+
- **que** >= 1.0 (for job monitoring)
|
|
208
|
+
- **exception-track** >= 0.1 (for exception tracking)
|
|
134
209
|
|
|
135
|
-
##
|
|
210
|
+
## Upgrading from 0.1.x
|
|
211
|
+
|
|
212
|
+
If you were using the previous Slack-based version:
|
|
213
|
+
|
|
214
|
+
1. Remove Slack/SNS configuration from your initializer
|
|
215
|
+
2. Remove `que-scheduler` if only used for Newshound
|
|
216
|
+
3. Update to new configuration format (see above)
|
|
217
|
+
4. Restart your Rails server
|
|
136
218
|
|
|
137
|
-
|
|
138
|
-
- **No exceptions showing**: Ensure `exception-track` gem is installed and logging
|
|
139
|
-
- **No job data**: Verify Que is configured and `que_jobs` table exists
|
|
140
|
-
- **Slack not receiving**: Verify webhook URL or API token is correct
|
|
219
|
+
The banner will now appear automatically for authorized users instead of sending Slack notifications.
|
|
141
220
|
|
|
142
221
|
## License
|
|
143
222
|
|
data/TRANSPORT_USAGE.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Transport Layer Usage
|
|
2
|
+
|
|
3
|
+
The Newshound gem now supports multiple transport adapters for sending notifications. You can choose between Slack (direct) and Amazon SNS based on your environment needs.
|
|
4
|
+
|
|
5
|
+
## Configuration
|
|
6
|
+
|
|
7
|
+
### Using Slack Transport (Default)
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
# config/initializers/newshound.rb
|
|
11
|
+
Newshound.configure do |config|
|
|
12
|
+
config.transport_adapter = :slack # This is the default
|
|
13
|
+
config.slack_webhook_url = ENV['SLACK_WEBHOOK_URL']
|
|
14
|
+
config.slack_channel = '#your-channel'
|
|
15
|
+
# ... other configurations
|
|
16
|
+
end
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Using SNS Transport
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
# config/initializers/newshound.rb
|
|
23
|
+
Newshound.configure do |config|
|
|
24
|
+
config.transport_adapter = :sns
|
|
25
|
+
config.sns_topic_arn = ENV['SNS_TOPIC_ARN']
|
|
26
|
+
config.aws_region = ENV['AWS_REGION'] || 'us-east-1'
|
|
27
|
+
|
|
28
|
+
# Optional: Provide AWS credentials explicitly
|
|
29
|
+
# If not provided, will use default AWS credential chain
|
|
30
|
+
config.aws_access_key_id = ENV['AWS_ACCESS_KEY_ID']
|
|
31
|
+
config.aws_secret_access_key = ENV['AWS_SECRET_ACCESS_KEY']
|
|
32
|
+
|
|
33
|
+
# ... other configurations
|
|
34
|
+
end
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Environment-based Configuration
|
|
38
|
+
|
|
39
|
+
You can switch transport based on environment:
|
|
40
|
+
|
|
41
|
+
```ruby
|
|
42
|
+
# config/initializers/newshound.rb
|
|
43
|
+
Newshound.configure do |config|
|
|
44
|
+
if Rails.env.production?
|
|
45
|
+
# Use SNS in production to route through AWS infrastructure
|
|
46
|
+
config.transport_adapter = :sns
|
|
47
|
+
config.sns_topic_arn = ENV['SNS_TOPIC_ARN']
|
|
48
|
+
config.aws_region = ENV['AWS_REGION']
|
|
49
|
+
else
|
|
50
|
+
# Use direct Slack in development/staging
|
|
51
|
+
config.transport_adapter = :slack
|
|
52
|
+
config.slack_webhook_url = ENV['SLACK_WEBHOOK_URL']
|
|
53
|
+
config.slack_channel = '#dev-notifications'
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Common configurations
|
|
57
|
+
config.report_time = "09:00"
|
|
58
|
+
config.exception_limit = 4
|
|
59
|
+
config.time_zone = "America/New_York"
|
|
60
|
+
end
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Custom Transport Adapters
|
|
64
|
+
|
|
65
|
+
You can also create your own transport adapter:
|
|
66
|
+
|
|
67
|
+
```ruby
|
|
68
|
+
class MyCustomTransport < Newshound::Transport::Base
|
|
69
|
+
def deliver(message)
|
|
70
|
+
# Your custom delivery logic here
|
|
71
|
+
# Return true on success, false on failure
|
|
72
|
+
|
|
73
|
+
# Example: Send to custom API endpoint
|
|
74
|
+
response = HTTParty.post(
|
|
75
|
+
'https://api.example.com/notifications',
|
|
76
|
+
body: message.to_json,
|
|
77
|
+
headers: { 'Content-Type' => 'application/json' }
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
response.success?
|
|
81
|
+
rescue StandardError => e
|
|
82
|
+
logger.error "Failed to deliver: #{e.message}"
|
|
83
|
+
false
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Use the custom transport
|
|
88
|
+
Newshound.configure do |config|
|
|
89
|
+
config.transport_adapter = MyCustomTransport
|
|
90
|
+
# ... other configurations
|
|
91
|
+
end
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## AWS SNS Setup
|
|
95
|
+
|
|
96
|
+
If using SNS transport, ensure you have:
|
|
97
|
+
|
|
98
|
+
1. Created an SNS topic in AWS
|
|
99
|
+
2. Subscribed your Slack webhook URL to the SNS topic
|
|
100
|
+
3. Configured proper IAM permissions for publishing to the topic
|
|
101
|
+
4. Installed the aws-sdk-sns gem (it's optional):
|
|
102
|
+
|
|
103
|
+
```ruby
|
|
104
|
+
# Add to your Gemfile if using SNS
|
|
105
|
+
gem 'aws-sdk-sns', '~> 1.0'
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Testing
|
|
109
|
+
|
|
110
|
+
The transport layer is fully testable. You can inject mock transports in your tests:
|
|
111
|
+
|
|
112
|
+
```ruby
|
|
113
|
+
# In your tests
|
|
114
|
+
mock_transport = double('Transport', deliver: true)
|
|
115
|
+
notifier = Newshound::SlackNotifier.new(transport: mock_transport)
|
|
116
|
+
notifier.post({ text: "Test message" })
|
|
117
|
+
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
|
|
5
|
+
module Newshound
|
|
6
|
+
module Generators
|
|
7
|
+
class InstallGenerator < Rails::Generators::Base
|
|
8
|
+
source_root File.expand_path("templates", __dir__)
|
|
9
|
+
|
|
10
|
+
desc "Configures Newshound for your Rails application"
|
|
11
|
+
|
|
12
|
+
def create_initializer
|
|
13
|
+
template "newshound.rb", "config/initializers/newshound.rb"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def display_post_install_message
|
|
17
|
+
say ""
|
|
18
|
+
say "===============================================================================", :green
|
|
19
|
+
say " Newshound has been successfully installed!", :green
|
|
20
|
+
say ""
|
|
21
|
+
say " Next steps:", :yellow
|
|
22
|
+
say " 1. Configure authorized roles in config/initializers/newshound.rb"
|
|
23
|
+
say " 2. Make sure your User model has a role attribute (or customize authorization)"
|
|
24
|
+
say " 3. Restart your Rails server"
|
|
25
|
+
say ""
|
|
26
|
+
say " The Newshound banner will automatically appear at the top of pages for"
|
|
27
|
+
say " authorized users (developers and super_users by default)."
|
|
28
|
+
say ""
|
|
29
|
+
say " To test the reporters, run:", :cyan
|
|
30
|
+
say " rake newshound:test_exceptions"
|
|
31
|
+
say " rake newshound:test_jobs"
|
|
32
|
+
say ""
|
|
33
|
+
say " For more information, visit:", :blue
|
|
34
|
+
say " https://github.com/salbanez/newshound"
|
|
35
|
+
say "===============================================================================", :green
|
|
36
|
+
say ""
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Newshound.configure do |config|
|
|
4
|
+
# Enable or disable Newshound completely
|
|
5
|
+
# When enabled, the banner will be shown to authorized users
|
|
6
|
+
# Default is true
|
|
7
|
+
config.enabled = true
|
|
8
|
+
|
|
9
|
+
# Maximum number of exceptions to include in banner
|
|
10
|
+
# Default is 10
|
|
11
|
+
config.exception_limit = 10
|
|
12
|
+
|
|
13
|
+
# User roles that are authorized to view the Newshound banner
|
|
14
|
+
# These should match the role values in your User model
|
|
15
|
+
# Default is [:developer, :super_user]
|
|
16
|
+
config.authorized_roles = [:developer, :super_user]
|
|
17
|
+
|
|
18
|
+
# Method name to call to get the current user
|
|
19
|
+
# Most apps use :current_user (Devise, etc.)
|
|
20
|
+
# Default is :current_user
|
|
21
|
+
config.current_user_method = :current_user
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Advanced: Custom authorization logic
|
|
25
|
+
# If the default role-based authorization doesn't fit your needs,
|
|
26
|
+
# you can provide a custom authorization block:
|
|
27
|
+
#
|
|
28
|
+
# Newshound.authorize_with do |controller|
|
|
29
|
+
# # Your custom logic here
|
|
30
|
+
# # Return true to show the banner, false to hide it
|
|
31
|
+
# controller.current_user&.admin?
|
|
32
|
+
# end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Newshound
|
|
4
|
+
module Authorization
|
|
5
|
+
class << self
|
|
6
|
+
# Check if the current user/controller is authorized to view Newshound data
|
|
7
|
+
def authorized?(controller)
|
|
8
|
+
return false unless Newshound.configuration.enabled
|
|
9
|
+
|
|
10
|
+
# Use custom authorization block if provided
|
|
11
|
+
if Newshound.configuration.authorization_block
|
|
12
|
+
return Newshound.configuration.authorization_block.call(controller)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Default authorization: check if current_user has an authorized role
|
|
16
|
+
user = current_user_from(controller)
|
|
17
|
+
return false unless user
|
|
18
|
+
|
|
19
|
+
user_role = user_role_from(user)
|
|
20
|
+
return false unless user_role
|
|
21
|
+
|
|
22
|
+
Newshound.configuration.authorized_roles.include?(user_role.to_sym)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def current_user_from(controller)
|
|
28
|
+
method_name = Newshound.configuration.current_user_method
|
|
29
|
+
return nil unless controller.respond_to?(method_name)
|
|
30
|
+
|
|
31
|
+
controller.send(method_name)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def user_role_from(user)
|
|
35
|
+
return nil unless user
|
|
36
|
+
|
|
37
|
+
# Try common role attribute names
|
|
38
|
+
[:role, :user_role, :type].each do |attr|
|
|
39
|
+
return user.send(attr) if user.respond_to?(attr)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
nil
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -2,23 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
module Newshound
|
|
4
4
|
class Configuration
|
|
5
|
-
attr_accessor :
|
|
6
|
-
:
|
|
5
|
+
attr_accessor :exception_limit, :enabled, :authorized_roles,
|
|
6
|
+
:current_user_method, :authorization_block
|
|
7
7
|
|
|
8
8
|
def initialize
|
|
9
|
-
@
|
|
10
|
-
@slack_channel = "#general"
|
|
11
|
-
@report_time = "09:00"
|
|
12
|
-
@exception_limit = 4
|
|
13
|
-
@time_zone = "America/New_York"
|
|
9
|
+
@exception_limit = 10
|
|
14
10
|
@enabled = true
|
|
11
|
+
@authorized_roles = [:developer, :super_user]
|
|
12
|
+
@current_user_method = :current_user
|
|
13
|
+
@authorization_block = nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Allow custom authorization logic
|
|
17
|
+
def authorize_with(&block)
|
|
18
|
+
@authorization_block = block
|
|
15
19
|
end
|
|
16
20
|
|
|
17
21
|
def valid?
|
|
18
|
-
|
|
19
|
-
return false if slack_webhook_url.nil? || slack_webhook_url.empty?
|
|
20
|
-
|
|
21
|
-
true
|
|
22
|
+
enabled
|
|
22
23
|
end
|
|
23
24
|
end
|
|
24
25
|
end
|
|
@@ -2,9 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
module Newshound
|
|
4
4
|
class ExceptionReporter
|
|
5
|
+
attr_reader :exception_source, :configuration, :time_range
|
|
6
|
+
|
|
7
|
+
def initialize(exception_source: nil, configuration: nil, time_range: 24.hours)
|
|
8
|
+
@exception_source = exception_source || (defined?(ExceptionTrack::Log) ? ExceptionTrack::Log : nil)
|
|
9
|
+
@configuration = configuration || Newshound.configuration
|
|
10
|
+
@time_range = time_range
|
|
11
|
+
end
|
|
12
|
+
|
|
5
13
|
def generate_report
|
|
6
14
|
return no_exceptions_block if recent_exceptions.empty?
|
|
7
|
-
|
|
15
|
+
|
|
8
16
|
[
|
|
9
17
|
{
|
|
10
18
|
type: "section",
|
|
@@ -24,12 +32,12 @@ module Newshound
|
|
|
24
32
|
end
|
|
25
33
|
|
|
26
34
|
def fetch_recent_exceptions
|
|
27
|
-
return [] unless
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
.where("created_at >= ?",
|
|
35
|
+
return [] unless exception_source
|
|
36
|
+
|
|
37
|
+
exception_source
|
|
38
|
+
.where("created_at >= ?", time_range.ago)
|
|
31
39
|
.order(created_at: :desc)
|
|
32
|
-
.limit(
|
|
40
|
+
.limit(configuration.exception_limit)
|
|
33
41
|
end
|
|
34
42
|
|
|
35
43
|
def format_exceptions
|
|
@@ -62,9 +70,11 @@ module Newshound
|
|
|
62
70
|
end
|
|
63
71
|
|
|
64
72
|
def exception_count(exception)
|
|
65
|
-
|
|
73
|
+
return 0 unless exception_source
|
|
74
|
+
|
|
75
|
+
exception_source
|
|
66
76
|
.where(exception_class: exception.exception_class)
|
|
67
|
-
.where("created_at >= ?",
|
|
77
|
+
.where("created_at >= ?", time_range.ago)
|
|
68
78
|
.count
|
|
69
79
|
end
|
|
70
80
|
|