safetynet 0.0.1 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2572c7d4bb6b380f19be2ac509527dd742d3f1ee
4
- data.tar.gz: 4fd376f510b59f5d3a44a6462aa67622a2b1d4ff
3
+ metadata.gz: c82ab26e4311dd4cee67b3512af96ce1a3cd871d
4
+ data.tar.gz: f7d833205366907799b196294574314e756a7694
5
5
  SHA512:
6
- metadata.gz: 36b3699df9defb2a5926a544a2bc0737c57f1083826d83b265e395e9a11732db4ad592faebc7300162044ca0f9399022abf74af71d2c1516888aea66d6eb68c4
7
- data.tar.gz: 869a7e230e379985b11ae7f014bc0127a83479e34928c04512e023c19c92e786e2331bee6bff0e2d20a74fc91a7722e9a422c39386af886311dfd9d2612c43a3
6
+ metadata.gz: 3413d6714950b1ea54811c4caae76bbb47c4ac0a2f14306f2e7700ede475fb99e9bfbf9510d8138c7df349208db86a745d121a71d67524c636d87c1ca7d10774
7
+ data.tar.gz: ae9511d5345b41d51991862041bf39e420e479f38167b64428a7481bb6f0f3efe5e121e3bce988e8ef7be65de1f0bc5ce50d95feba68826b899d1836f42d3a50
data/README.md CHANGED
@@ -1,8 +1,10 @@
1
1
  # Safetynet
2
2
 
3
- TODO: Write a gem description
3
+ Stop communication problems before they happen
4
4
 
5
- ## Installation
5
+ Safetynet keeps track of email communications by user/email and ActionMailer message. If the same message is sent to the same user multiple times within the allowed timeframe, it will be blocked from delivery and notify system admins. The messages are filterable in a way similar to controller filters, and the checking method can be called by itself outside the normal hooks for additional throttling (i.e. SMS sending, push notifications, etc.).
6
+
7
+ ## Rails Installation
6
8
 
7
9
  Add this line to your application's Gemfile:
8
10
 
@@ -11,19 +13,76 @@ Add this line to your application's Gemfile:
11
13
  And then execute:
12
14
 
13
15
  $ bundle
16
+ $ rails generate safetynet
17
+ $ rake db:migrate
18
+
19
+ The generator creates two files:
14
20
 
15
- Or install it yourself as:
21
+ 1. a file under `config/initializers/safetynet.rb` configuring Safetynet with project-specific settings.
22
+ 2. a migration file to create the safetynet_histories table
16
23
 
17
- $ gem install safetynet
18
24
 
19
25
  ## Usage
20
26
 
21
- TODO: Write usage instructions here
27
+ ###Applied to a mailer
28
+
29
+ Add the safetynet method to an ActionMailer::Base class with the following structure:
30
+
31
+ safetynet({
32
+ channel,
33
+ filters,
34
+ options: {
35
+ email: {
36
+ limit: 1,
37
+ timeframe: 30.minutes
38
+ }
39
+ }
40
+ })
41
+
42
+ And a description of each:
43
+
44
+ |Field|Type|Description|
45
+ |:-|:-|:-|
46
+ |**channel** |Symbol |The category of methods to watch (email/sms/etc.) -- see options below|
47
+ |**filters** |Hash |Hash of method names to watch (email only) that fits after_action requirements|
48
+ |**options** |Hash |Contains a hash for each channel and includes the next 2 fields|
49
+ |**limit** |Integer |Maximum # of methods for this channel (default: 1)|
50
+ |**timeframe** |Integer |Minimum allowed timeframe between last successful method call (default: 30.minutes)|
51
+
52
+
53
+ **Note:** Defaults to configured channel, method, and Safetynet configuration limit & timeframe for the channel
54
+
55
+ ####Example:
56
+
57
+ class UserMailer < ActionMailer::Base
58
+ include Safetynet
59
+ safetynet :email, {except: [:user_registration_email, :forgot_password_email]}
60
+ end
61
+
62
+
63
+
64
+ ###Standalone usage on a class
65
+
66
+
67
+ ####Example:
68
+
69
+ class User < ActiveRecord::Base
70
+ include Safetynet
71
+ safetynet :sms
72
+
73
+ def send_sms
74
+ if permit_delivery?(self)
75
+ ...
76
+ end
77
+ end
78
+ end
79
+
22
80
 
23
81
  ## Contributing
24
82
 
25
- 1. Fork it ( https://github.com/[my-github-username]/safetynet/fork )
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create a new Pull Request
83
+ 1. Create an issue
84
+ 2. Fork it ( https://github.com/arktisklada/safetynet/fork )
85
+ 3. Create your feature branch (`git checkout -b my-new-feature`)
86
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
87
+ 5. Push to the branch (`git push origin my-new-feature`)
88
+ 6. Create a new Pull Request
data/Rakefile CHANGED
@@ -1,2 +1,32 @@
1
- require "bundler/gem_tasks"
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
2
6
 
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Safetynet'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+ Bundler::GemHelper.install_tasks
21
+
22
+ require 'rake/testtask'
23
+
24
+ Rake::TestTask.new(:test) do |t|
25
+ t.libs << 'lib'
26
+ t.libs << 'test'
27
+ t.pattern = 'test/**/*_test.rb'
28
+ t.verbose = false
29
+ end
30
+
31
+
32
+ task default: :test
@@ -0,0 +1,46 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+
4
+ class SafetynetGenerator < Rails::Generators::Base
5
+ include Rails::Generators::Migration
6
+ source_root File.expand_path('../templates', __FILE__)
7
+ desc "Creates the Safetynet initializer file at config/initializers/safetynet.rb and a migration"
8
+
9
+
10
+ def self.next_migration_number(path)
11
+ unless @prev_migration_nr
12
+ @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
13
+ else
14
+ @prev_migration_nr += 1
15
+ end
16
+ @prev_migration_nr.to_s
17
+ end
18
+
19
+ def install
20
+ generate_initializer
21
+ generate_migration
22
+ end
23
+
24
+
25
+ private
26
+
27
+ def generate_initializer
28
+ template 'initializer.rb', 'config/initializers/safetynet.rb'
29
+ end
30
+
31
+ def configuration_output
32
+ output = <<-eos
33
+ Rails.configuration.safetynet = {
34
+ email: {
35
+ limit: Rails.env.development? ? 1000 : 1,
36
+ timeframe: 1.hour
37
+ }
38
+ }
39
+ eos
40
+ end
41
+
42
+ def generate_migration
43
+ puts SafetynetGenerator.source_root
44
+ migration_template 'db/migrate/1_create_safetynet_histories.rb', 'db/migrate/create_safetynet_histories.rb'
45
+ end
46
+ end
@@ -0,0 +1,16 @@
1
+ class CreateSafetynetHistories < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :safetynet_histories do |t|
4
+ t.string :address
5
+ t.string :channel
6
+ t.string :method
7
+ t.datetime :created_at
8
+ end
9
+
10
+ add_index :safetynet_histories, [:address, :channel, :method, :created_at], name: 'safetynet_histories_idx'
11
+ end
12
+
13
+ def self.down
14
+ drop_table :safetynet_histories
15
+ end
16
+ end
@@ -0,0 +1,4 @@
1
+ <% if Rails::VERSION::MAJOR < 3 && Rails::VERSION::MINOR < 2 -%>
2
+ require 'safetynet'
3
+ <% end -%>
4
+ <%= configuration_output %>
@@ -0,0 +1,5 @@
1
+ require 'rails/engine'
2
+ module Safetynet
3
+ class Engine < Rails::Engine
4
+ end
5
+ end
@@ -1,3 +1,3 @@
1
1
  module Safetynet
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
data/lib/safetynet.rb CHANGED
@@ -1,16 +1,19 @@
1
- require "safetynet/version"
1
+ require 'safetynet/version'
2
2
  require 'active_support/concern'
3
+ require 'active_support/core_ext/numeric/time'
3
4
 
4
5
  module Safetynet
5
6
  extend ActiveSupport::Concern
6
7
 
8
+
7
9
  # Saves a record for the current method
8
- def safe_safetynet_delivery(user, channel, method)
10
+ def safe_safetynet_delivery(address, channel, method)
9
11
  options = self.class.safetynet_options
10
- log = SafetynetLog.new({
11
- user_id: user.id,
12
+ log = Safetynet::History.new({
13
+ address: address,
12
14
  method: method,
13
- channel: channel.to_s
15
+ channel: channel.to_s,
16
+ created_at: Time.now
14
17
  })
15
18
  log.save
16
19
  end
@@ -37,7 +40,7 @@ module Safetynet
37
40
  # end
38
41
  # end
39
42
  def permit_delivery?(address, channel=nil, method=nil, limit=nil, timeframe=nil)
40
- # Skip check if email is whitelisted
43
+ # Skip check if address is whitelisted
41
44
  return true if is_whitelisted?(address)
42
45
 
43
46
  options = self.class.safetynet_options
@@ -50,7 +53,7 @@ module Safetynet
50
53
  # Query the model to determine if delivery is permitted
51
54
  permit_delivery = true
52
55
  if limit != false
53
- count_query = SafetynetLog.where({
56
+ count_query = Safetynet::History.where({
54
57
  address: address,
55
58
  channel: channel,
56
59
  method: method
@@ -102,9 +105,9 @@ module Safetynet
102
105
  permit_delivery
103
106
  end
104
107
 
105
- # All example.com emails are whitelisted
106
- def is_whitelisted?(email)
107
- !!(self.class.safetynet_options[:whitelist].match(email))
108
+ # Permits all whitelisted addresses by regex
109
+ def is_whitelisted?(address)
110
+ !!(self.class.safetynet_options[:whitelist].match(address))
108
111
  end
109
112
 
110
113
  module ClassMethods
@@ -147,3 +150,5 @@ module Safetynet
147
150
  end
148
151
  end
149
152
  end
153
+
154
+ ActiveRecord::Base.send :include, Safetynet
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :safetynet do
3
+ # # Task goes here
4
+ # end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safetynet
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - arktisklada
@@ -10,6 +10,34 @@ bindir: bin
10
10
  cert_chain: []
11
11
  date: 2015-05-22 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: bundler
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +66,34 @@ dependencies:
38
66
  - - ">="
39
67
  - !ruby/object:Gem::Version
40
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec-rails
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
41
97
  description: 'Safetynet keeps track of email communications by user/email and ActionMailer
42
98
  message. If the same message is sent to the same user multiple times within the
43
99
  allowed timeframe, it will be blocked from delivery and notify system admins. The
@@ -50,15 +106,17 @@ executables: []
50
106
  extensions: []
51
107
  extra_rdoc_files: []
52
108
  files:
53
- - ".gitignore"
54
- - Gemfile
55
- - LICENSE.txt
109
+ - LICENSE.TXT
56
110
  - README.md
57
111
  - Rakefile
112
+ - lib/rails/generators/safetynet/safetynet_generator.rb
113
+ - lib/rails/generators/safetynet/templates/db/migrate/1_create_safetynet_histories.rb
114
+ - lib/rails/generators/safetynet/templates/initializer.rb
58
115
  - lib/safetynet.rb
116
+ - lib/safetynet/engine.rb
59
117
  - lib/safetynet/version.rb
60
- - safetynet.gemspec
61
- homepage: ''
118
+ - lib/tasks/safetynet_tasks.rake
119
+ homepage: https://github.com/arktisklada/safetynet
62
120
  licenses:
63
121
  - MIT
64
122
  metadata: {}
data/.gitignore DELETED
@@ -1,22 +0,0 @@
1
- *.gem
2
- *.rbc
3
- .bundle
4
- .config
5
- .yardoc
6
- Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
18
- *.bundle
19
- *.so
20
- *.o
21
- *.a
22
- mkmf.log
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in safetynet.gemspec
4
- gemspec
data/safetynet.gemspec DELETED
@@ -1,23 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'safetynet/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "safetynet"
8
- spec.version = Safetynet::VERSION
9
- spec.authors = ["arktisklada"]
10
- spec.email = ["mail@enorganik.com"]
11
- spec.summary = %q{Stop communication problems before they happen}
12
- spec.description = %q{Safetynet keeps track of email communications by user/email and ActionMailer message. If the same message is sent to the same user multiple times within the allowed timeframe, it will be blocked from delivery and notify system admins. The messages are filterable in a way similar to controller filters, and the checking method can be called by itself outside the normal hooks for additional throttling (i.e. SMS sending, push notifications, etc.). }
13
- spec.homepage = ""
14
- spec.license = "MIT"
15
-
16
- spec.files = `git ls-files -z`.split("\x0")
17
- # spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
20
-
21
- spec.add_development_dependency "bundler", "~> 1.6"
22
- spec.add_development_dependency "rake"
23
- end
File without changes