tyrant 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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