tyrant 0.0.1 → 0.0.2

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: d2f54842fb5f05856d5b2117e524ecca85e359e7
4
- data.tar.gz: 73dc1f4b6625fb1f68a34eecbbf098fc4cb4c718
3
+ metadata.gz: 0686d74d8af9df770a7c8eedd729b6e375e0bed2
4
+ data.tar.gz: f079966822ca11c34637655e8d520b96941f664e
5
5
  SHA512:
6
- metadata.gz: 815200c2c369b371f8ddf167bd54261b8d6475860b7644753dd810c526b640728d799e1f1befcf8e8dd404209d8a761ed5d1c04f93e42bd20b05485383bf2735
7
- data.tar.gz: 43eddef2195258978ee7ddebd89fb50c4aca79310f13a9562ddcb85d504a30fac9529b793e0ca117d5816050a8e5190e478d4598a14fe3edf05774bcc042d24d
6
+ metadata.gz: b46e96e5e3c37e22069bd40c05633940ccd00974c0a6805f7805c793b518271e080c35b44c9107404c5577d1f3039554cf85546e2bd0d458c3c90d9d4b83a2f9
7
+ data.tar.gz: a716baf50d9fa237adc43eb47d0ec6da6e01dfeb0b565df26de551eb6a64ff11fffc7828c0820256ef6bc5d1a9e93968186b36f3b4f86fa1a8b405c5fce661de
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in tyrant.gemspec
4
4
  gemspec
5
+
6
+ # gem "disposable", path: "../disposable"
data/README.md CHANGED
@@ -1,38 +1,69 @@
1
1
  # Tyrant
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/tyrant`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ _"Freedom choked in dread we live, since tyrant was enthroned."_
4
4
 
5
- TODO: Delete this and the text above, and describe your gem
5
+ Tyrant implements all common steps of authorization workflows using overridable _operations_. It allows a quick setup of sign in, sign up, forgot password, etc. Tryrant works well in Rails, but plays well with any Ruby environment.
6
6
 
7
- ## Installation
7
+ Operations are provided for the following steps.
8
8
 
9
- Add this line to your application's Gemfile:
9
+ * SignIn
10
+ * Confirmed
11
+ * Hammer protection (3x wrong blabla)
12
+ * Sticky (Remember me)
13
+ * SignUp
14
+ * SignOut
15
+ * ResetPassword
16
+ * Forgot pw
17
+
18
+
19
+ ## Operations
20
+
21
+ trb instead of pushing into controller
22
+
23
+
24
+ Tyrant exposes its public API using operations.
25
+
26
+ Operations are the pivotal element in the [Trailblazer architecture](https://github.com/apotonick/trailblazer). When it comes to customization, Tyrant doesn't rely on a "hopefully complete" configuration language as Devise does it.
27
+
28
+ Tyrant allows you to customize with Ruby. You can override entire workflow steps (operations), forms and validations (contracts) or methods using simple object-orientation and a clean API.
29
+
30
+
31
+ This means you can easily use them in Rails controllers.
10
32
 
11
33
  ```ruby
12
- gem 'tyrant'
34
+ class SessionController < ApplicationController
35
+ def sign_in
36
+ run Tyrant::SignIn
37
+ end
13
38
  ```
14
39
 
15
- And then execute:
40
+ You can also run the public API in any other Ruby environment, e.g. a console or a Roda action.
16
41
 
17
- $ bundle
42
+ ```ruby
43
+ Tyrant::SignIn.run(params)
44
+ ```
18
45
 
19
- Or install it yourself as:
46
+ Tyrant provides forms for all workflow steps. using Reform objects that are embedded into the operations.
20
47
 
21
- $ gem install tyrant
22
48
 
23
- ## Usage
49
+ => Customize with inheritance, or override. Or just don't use the operation and write your own "step".
24
50
 
25
- TODO: Write usage instructions here
26
51
 
27
- ## Development
52
+ ## Installation
28
53
 
29
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
54
+ Add this line to your application's Gemfile:
30
55
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
56
+ ```ruby
57
+ gem 'tyrant'
58
+ ```
59
+
60
+ ## Rails
32
61
 
33
- ## Contributing
62
+ Tyrant comes with a railtie to provide you an initializer. In Rails, add this to an initializer.
34
63
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/tyrant.
64
+ ```ruby
65
+ require "tyrant/railtie"
66
+ ```
36
67
 
37
68
 
38
69
  ## License
@@ -3,3 +3,7 @@ require "tyrant/version"
3
3
  module Tyrant
4
4
  # Your code goes here...
5
5
  end
6
+
7
+ require "disposable/twin"
8
+ require "tyrant/authenticatable"
9
+ require "tyrant/session"
@@ -0,0 +1,76 @@
1
+ require "disposable/twin/struct"
2
+
3
+ module Tyrant
4
+ # Encapsulates authentication management logic for a particular user.
5
+ class Authenticatable < Disposable::Twin
6
+ feature Default
7
+ feature Sync # FIXME: really?
8
+
9
+ property :auth_meta_data, default: Hash.new do
10
+ include Struct
11
+ property :confirmation_token
12
+ property :confirmed_at
13
+ property :confirmation_created_at
14
+ property :password_digest
15
+ end
16
+
17
+ module Confirm
18
+ def confirmable!
19
+ auth_meta_data.confirmation_token = "asdfasdfasfasfasdfasdf"
20
+ auth_meta_data.confirmation_created_at = DateTime.now
21
+ self
22
+ end
23
+
24
+ # without token, this decides whether the user model can be activated (e.g. via "set a password").
25
+ # with token, this additionally tests if the token is correct.
26
+ def confirmable?(token=false)
27
+ persisted_token = auth_meta_data.confirmation_token
28
+
29
+ # TODO: add expiry etc.
30
+ return false unless (persisted_token.is_a?(String) and persisted_token.size > 0)
31
+
32
+ return compare_token(token) unless token==false
33
+ true
34
+ end
35
+
36
+ # alias_method :confirmed?, :confirmable?
37
+ def confirmed?
38
+ not auth_meta_data.confirmed_at.nil?
39
+ end
40
+
41
+ def confirmed!(confirmed_at=DateTime.now)
42
+ auth_meta_data.confirmation_token = nil
43
+ auth_meta_data.confirmed_at = confirmed_at # TODO: test optional arg.
44
+ end
45
+
46
+ def confirmation_token
47
+ auth_meta_data.confirmation_token
48
+ end
49
+
50
+ private
51
+ def compare_token(token)
52
+ token == auth_meta_data.confirmation_token
53
+ end
54
+ end # Confirm
55
+ include Confirm
56
+
57
+
58
+ require "bcrypt"
59
+ module Digest
60
+ def digest
61
+ return unless auth_meta_data.password_digest
62
+ BCrypt::Password.new(auth_meta_data.password_digest)
63
+ end
64
+
65
+ def digest!(password)
66
+ auth_meta_data.password_digest = BCrypt::Password.create(password)
67
+ end
68
+
69
+ def digest?(password)
70
+ digest == password
71
+ end
72
+ end
73
+ include Digest
74
+
75
+ end
76
+ end
@@ -0,0 +1,16 @@
1
+ module Tyrant
2
+ class Railtie < Rails::Railtie
3
+ require "warden"
4
+
5
+ # DISCUSS: it will be configurable what user class etc. and might be moved to Ops.
6
+ config.app_middleware.use Warden::Manager do |config|
7
+ Warden::Manager.serialize_into_session do |user|
8
+ user.id
9
+ end
10
+
11
+ Warden::Manager.serialize_from_session do |id|
12
+ User.find_by(id: id)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ module Tyrant
2
+ # HTTP/Warden session-specific behavior.
3
+ class Session
4
+ def initialize(warden)
5
+ @warden = warden
6
+ end
7
+
8
+ def current_user
9
+ @warden.user
10
+ end
11
+
12
+ def signed_in?
13
+ @warden.user
14
+ end
15
+
16
+ def sign_in!(user)
17
+ @warden.set_user(user)
18
+ end
19
+
20
+ def sign_out!
21
+ @warden.logout
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,53 @@
1
+ require "trailblazer/operation"
2
+ require "active_model"
3
+ require "reform/form/active_model/validations" # TODO: this will get replaced with Lotus.
4
+ require "reform/form/validation/unique_validator.rb"
5
+ module Tyrant
6
+ # SignUp will come and implement to-be-confirmed sign up.
7
+ class SignUp < Trailblazer::Operation
8
+ class Confirmed < Trailblazer::Operation
9
+ include CRUD
10
+ model User, :create
11
+
12
+ contract do
13
+ include Reform::Form::ActiveModel::Validations
14
+
15
+ property :email
16
+ property :password, virtual: true
17
+ property :confirm_password, virtual: true
18
+
19
+ validates :email, :password, :confirm_password, presence: true
20
+ # validates :email, email: true, unique: true
21
+ validate :password_ok?
22
+
23
+ private
24
+ # TODO: more, like minimum 6 chars, etc.
25
+ def password_ok?
26
+ return unless email and password
27
+ errors.add(:password, "Passwords don't match") if password != confirm_password
28
+ end
29
+ end
30
+
31
+
32
+ # sucessful signup:
33
+ # * hash password, set confirmed
34
+ # * hash password, set unconfirmed with token etc.
35
+
36
+ # * no password, unconfirmed, needs password.
37
+ def process(params)
38
+ validate(params[:user]) do |contract|
39
+ update!
40
+
41
+ contract.save # save User with email.
42
+ end
43
+ end
44
+
45
+ def update!
46
+ auth = Tyrant::Authenticatable.new(contract.model)
47
+ auth.digest!(contract.password) # contract.auth_meta_data.password_digest = ..
48
+ auth.confirmed!
49
+ auth.sync
50
+ end
51
+ end
52
+ end
53
+ end
@@ -1,3 +1,3 @@
1
1
  module Tyrant
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
@@ -13,9 +13,6 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = "http://github.com/apotonick/tyrant"
14
14
  spec.license = "MIT"
15
15
 
16
- # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
17
- # delete this section to allow pushing this gem to any host.
18
-
19
16
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
17
  spec.bindir = "exe"
21
18
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
@@ -24,4 +21,12 @@ Gem::Specification.new do |spec|
24
21
  spec.add_development_dependency "bundler", "~> 1.10"
25
22
  spec.add_development_dependency "rake", "~> 10.0"
26
23
  spec.add_development_dependency "minitest"
24
+
25
+ spec.add_development_dependency "activemodel"
26
+
27
+ spec.add_dependency "trailblazer"
28
+ spec.add_dependency "reform", "~> 2.0"
29
+ spec.add_dependency "disposable", ">= 0.1.11"
30
+
31
+ spec.add_dependency "bcrypt"
27
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tyrant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nick Sutterer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-07-01 00:00:00.000000000 Z
11
+ date: 2015-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,76 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: activemodel
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: trailblazer
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
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: reform
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: disposable
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: 0.1.11
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 0.1.11
111
+ - !ruby/object:Gem::Dependency
112
+ name: bcrypt
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
55
125
  description: Agnostic authorization component for Trailblazer.
56
126
  email:
57
127
  - apotonick@gmail.com
@@ -65,9 +135,11 @@ files:
65
135
  - LICENSE.txt
66
136
  - README.md
67
137
  - Rakefile
68
- - bin/console
69
- - bin/setup
70
138
  - lib/tyrant.rb
139
+ - lib/tyrant/authenticatable.rb
140
+ - lib/tyrant/railtie.rb
141
+ - lib/tyrant/session.rb
142
+ - lib/tyrant/sign_up.rb
71
143
  - lib/tyrant/version.rb
72
144
  - tyrant.gemspec
73
145
  homepage: http://github.com/apotonick/tyrant
@@ -95,3 +167,4 @@ signing_key:
95
167
  specification_version: 4
96
168
  summary: Agnostic authorization for Trailblazer.
97
169
  test_files: []
170
+ has_rdoc:
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "tyrant"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start
data/bin/setup DELETED
@@ -1,7 +0,0 @@
1
- #!/bin/bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
-
5
- bundle install
6
-
7
- # Do any other automated setup that you need to do here