authtown 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b75bcb24f21f87172f654d1d987c6fba611ffdd03b6a4bc65dc5e8aeed65324c
4
+ data.tar.gz: 62111ad44b4391e6a2300e38ede4e55638c4239a3d1f71fd74ce5a22613c9a53
5
+ SHA512:
6
+ metadata.gz: f9bd62d8b2e309d9adf91d8751d5d7a8843f7306220052790f98baf97b1c929140fb3f4661ed724df83417cf196a7f4590803f354f7524903e2213de7c59bbdf
7
+ data.tar.gz: d34c203ead7a8ae36a0e064cc2c4764d186705d95addc83b1c7d9c3a0ed2896e16e162a2eb80e2784a9ea9a93ece6da075b6466e21266a95fc1e4fb2abf9ea89
@@ -0,0 +1,32 @@
1
+ name: Tests
2
+
3
+ on:
4
+ pull_request:
5
+ branches:
6
+ - "*"
7
+ push:
8
+ branches:
9
+ - main
10
+
11
+ jobs:
12
+ build:
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ matrix:
16
+ ruby_version: [2.7.7, 3.0.5, 3.1.3, 3.2.0]
17
+ bridgetown_version: [1.2.0]
18
+ continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' }}
19
+ # Has to be top level to cache properly
20
+ env:
21
+ BUNDLE_JOBS: 3
22
+ BUNDLE_PATH: "vendor/bundle"
23
+ BRIDGETOWN_VERSION: ${{ matrix.bridgetown_version }}
24
+ steps:
25
+ - uses: actions/checkout@master
26
+ - name: Setup Ruby
27
+ uses: ruby/setup-ruby@v1
28
+ with:
29
+ ruby-version: ${{ matrix.ruby_version }}
30
+ bundler-cache: true
31
+ - name: Test with Rake
32
+ run: script/cibuild
data/.gitignore ADDED
@@ -0,0 +1,40 @@
1
+ /vendor
2
+ /.bundle/
3
+ /.yardoc
4
+ /Gemfile.lock
5
+ /_yardoc/
6
+ /coverage/
7
+ /doc/
8
+ /pkg/
9
+ /spec/reports/
10
+ /tmp/
11
+ *.bundle
12
+ *.so
13
+ *.o
14
+ *.a
15
+ mkmf.log
16
+ *.gem
17
+ Gemfile.lock
18
+ .bundle
19
+ .ruby-version
20
+
21
+ # Node
22
+ node_modules
23
+ .npm
24
+ .node_repl_history
25
+
26
+ # Yarn
27
+ yarn-error.log
28
+ yarn-debug.log*
29
+ .pnp/
30
+ .pnp.js
31
+
32
+ # Yarn Integrity file
33
+ .yarn-integrity
34
+
35
+ test/dest
36
+ .bridgetown-metadata
37
+ .bridgetown-cache
38
+ .bridgetown-webpack
39
+
40
+ .env
data/.rubocop.yml ADDED
@@ -0,0 +1,23 @@
1
+ require: rubocop-bridgetown
2
+
3
+ inherit_gem:
4
+ rubocop-bridgetown: .rubocop.yml
5
+
6
+ AllCops:
7
+ TargetRubyVersion: 3.1
8
+
9
+ Exclude:
10
+ - .gitignore
11
+ - .rubocop.yml
12
+ - "*.gemspec"
13
+
14
+ - Gemfile.lock
15
+ - CHANGELOG.md
16
+ - LICENSE.txt
17
+ - README.md
18
+ - Rakefile
19
+ - bridgetown.automation.rb
20
+
21
+ - script/**/*
22
+ - test/fixtures/**/*
23
+ - vendor/**/*
data/CHANGELOG.md ADDED
@@ -0,0 +1,14 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ - ...
11
+
12
+ ## [0.1.0] - YYYY-MM-DD
13
+
14
+ - Very early testing release of Authtown
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+ gemspec
5
+
6
+ gem "bridgetown", ENV["BRIDGETOWN_VERSION"] if ENV["BRIDGETOWN_VERSION"]
7
+
8
+ group :test do
9
+ gem "minitest"
10
+ gem "minitest-profile"
11
+ gem "minitest-reporters"
12
+ end
13
+
14
+ gem "solargraph", "~> 0.49.0"
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020-present
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # Authtown: Rodauth integration for Bridgetown
2
+
3
+ A Bridgetown plugin which provides authentication and account management via database access and SSR routes.
4
+
5
+ **WIP: not yet for public use!**
6
+
7
+ ## Installation
8
+
9
+ Run this command to add this plugin to your site's Gemfile:
10
+
11
+ ```shell
12
+ bundle add authtown
13
+ ```
14
+
15
+ Then add the initializer to your configuration in `config/initializers.rb`:
16
+
17
+ ```ruby
18
+ init :authtown
19
+ ```
20
+
21
+ ## Usage
22
+
23
+ The plugin will…
24
+
25
+ ## Testing
26
+
27
+ * Run `bundle exec rake test` to run the test suite
28
+ * Or run `script/cibuild` to validate with Rubocop and Minitest together.
29
+
30
+ ## Contributing
31
+
32
+ 1. Fork it (https://github.com/username/my-awesome-plugin/fork)
33
+ 2. Clone the fork using `git clone` to your local development machine.
34
+ 3. Create your feature branch (`git checkout -b my-new-feature`)
35
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
36
+ 5. Push to the branch (`git push origin my-new-feature`)
37
+ 6. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ t.libs << "lib"
7
+ t.test_files = FileList["test/**/test_*.rb"]
8
+ t.warning = false
9
+ end
10
+
11
+ task :default => :test
data/authtown.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/authtown/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "authtown"
7
+ spec.version = Authtown::VERSION
8
+ spec.author = "Bridgetown Team"
9
+ spec.email = "maintainers@bridgetownrb.com"
10
+ spec.summary = "Rodauth integration for Bridgetown"
11
+ spec.homepage = "https://github.com/bridgetownrb/authtown"
12
+ spec.license = "MIT"
13
+
14
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r!^(test|script|spec|features|frontend)/!) }
15
+ spec.test_files = spec.files.grep(%r!^test/!)
16
+ spec.require_paths = ["lib"]
17
+
18
+ spec.required_ruby_version = ">= 3.1"
19
+
20
+ spec.add_dependency "bridgetown", ">= 1.3.0", "< 2.0"
21
+ spec.add_dependency "rodauth", ">= 2.30"
22
+ spec.add_dependency "bcrypt", ">= 3.1"
23
+ spec.add_dependency "mail", ">= 2.8"
24
+
25
+ spec.add_development_dependency "bundler"
26
+ spec.add_development_dependency "rake", ">= 13.0"
27
+ spec.add_development_dependency "rubocop-bridgetown", "~> 0.3"
28
+ end
@@ -0,0 +1,51 @@
1
+ # If your plugin requires a lot of steps to get set up, consider writing an automation to help guide users.
2
+ # You could set up and configure all sorts of things, for example:
3
+ #
4
+ # add_gem("my_plugin")
5
+ #
6
+ # add_yarn_for_gem("my_plugin")
7
+ #
8
+ # add_initializer :"my_plugin" do
9
+ # <<~RUBY
10
+ # do
11
+ # some_config_key 12345
12
+ # end
13
+ # RUBY
14
+ # end
15
+ #
16
+ # create_builder "my_nifty_builder.rb" do
17
+ # <<~RUBY
18
+ # class MyNeatBuilder < SiteBuilder
19
+ # def build
20
+ # puts MyPlugin.hello
21
+ # end
22
+ # end
23
+ # RUBY
24
+ # end
25
+ #
26
+ # javascript_import do
27
+ # <<~JS
28
+ # import { MyPlugin } from "my_plugin"
29
+ # JS
30
+ # end
31
+ #
32
+ # javascript_import 'import "my_plugin/frontend/styles/index.css"'
33
+ #
34
+ # create_file "src/_data/plugin_data.yml" do
35
+ # <<~YAML
36
+ # data:
37
+ # goes: here
38
+ # YAML
39
+ # end
40
+ #
41
+ # color = ask("What's your favorite color?")
42
+ #
43
+ # append_to_file "bridgetown.config.yml" do
44
+ # <<~YAML
45
+ #
46
+ # my_plugin:
47
+ # favorite_color: #{color}
48
+ # YAML
49
+ # end
50
+ #
51
+ # Read the Automations documentation: https://www.bridgetownrb.com/docs/automations
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authtown
4
+ class Builder < Bridgetown::Builder
5
+ def build
6
+ helper(:rodauth) { helpers.view.resource.roda_app&.rodauth }
7
+ helper(:current_user) { Authtown::Current.user }
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authtown
4
+ module Routes
5
+ class InitRodauth < Bridgetown::Rack::Routes
6
+ priority :highest
7
+
8
+ route do |r|
9
+ rodauth.load_memory
10
+
11
+ init_current_user
12
+ Lifeform::Form.rodauth = rodauth
13
+
14
+ r.on "auth" do
15
+ r.rodauth
16
+ end
17
+ end
18
+
19
+ def init_current_user
20
+ Authtown::Current.user =
21
+ if rodauth.logged_in?
22
+ account_id = rodauth.account_from_session[:id]
23
+ User.find(account_id)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authtown
4
+ VERSION = "0.1.0"
5
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authtown::ViewMixin
4
+ def locals = @_route_locals
5
+
6
+ # TODO: this is super hacky
7
+ def view(*args, view_class: Bridgetown::ERBView, **kwargs) # rubocop:disable Metrics
8
+ kwargs = args.first if args.first.is_a?(Hash)
9
+
10
+ # If we're farming out to another view, let's go!
11
+ unless kwargs.empty?
12
+ response["X-Bridgetown-SSR"] = "1"
13
+
14
+ # UGH, hate special casing this
15
+ if kwargs.dig(:locals, :rodauth)&.prefix
16
+ kwargs[:template] =
17
+ "#{kwargs.dig(:locals, :rodauth).prefix.delete_prefix("/")}/#{kwargs[:template]}"
18
+ end
19
+
20
+ Bridgetown::Routes::Manifest.generate_manifest(bridgetown_site).each do |route|
21
+ file, localized_file_slugs = route
22
+
23
+ file_slug = localized_file_slugs.first
24
+
25
+ next unless file_slug == kwargs[:template]
26
+
27
+ Bridgetown::Routes::CodeBlocks.eval_route_file file, file_slug, self
28
+ route_block = Bridgetown::Routes::CodeBlocks.route_block(file_slug)
29
+ response.instance_variable_set(
30
+ :@_route_file_code, route_block.instance_variable_get(:@_route_file_code)
31
+ ) # could be nil
32
+ @_route_locals = kwargs[:locals]
33
+ return instance_exec(request, &route_block)
34
+ end
35
+
36
+ Bridgetown.logger.warn("Template not found: #{kwargs[:template]}")
37
+ return nil # couldn't find template, 404
38
+ end
39
+
40
+ response._fake_resource_view(
41
+ view_class:, roda_app: self, bridgetown_site:
42
+ )
43
+ end
44
+
45
+ def current_user = Authtown::Current.user
46
+ end
data/lib/authtown.rb ADDED
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bridgetown"
4
+ require "mail"
5
+ require "authtown/builder"
6
+ require "authtown/view_mixin"
7
+
8
+ # REQUIRES:
9
+ # init :"bridgetown-activerecord", sequel_support: :postgres
10
+
11
+ # ActiveRecord schema:
12
+ #
13
+ # class CreateUsers < ActiveRecord::Migration[7.0]
14
+ # def change
15
+ # create_table :users do |t|
16
+ # t.string :email, null: false, index: { unique: true }
17
+ # t.string :first_name
18
+ # t.string :password_hash, null: false
19
+ # t.timestamps
20
+ # end
21
+ # end
22
+ # end
23
+ #
24
+ # class CreateAccountRememberKeys < ActiveRecord::Migration[7.0]
25
+ # def change
26
+ # create_table :account_remember_keys do |t|
27
+ # t.foreign_key :users, column: :id
28
+ # t.string :key, null: false
29
+ # t.datetime :deadline, null: false
30
+ # end
31
+ # end
32
+ # end
33
+
34
+ class Authtown::Current < ActiveSupport::CurrentAttributes
35
+ # @!parse def self.user = User.new
36
+ attribute :user
37
+ end
38
+
39
+ # rubocop:disable Metrics/BlockLength
40
+ # @param config [Bridgetown::Configuration::ConfigurationDSL]
41
+ # @param rodauth_config [Proc]
42
+ Bridgetown.initializer :authtown do |
43
+ config,
44
+ rodauth_config: nil,
45
+ account_landing_page: "/account/profile"
46
+ |
47
+
48
+ config.only :server do
49
+ require "authtown/routes/rodauth"
50
+
51
+ # @param app [Class<Roda>]
52
+ config.roda do |app|
53
+ app.prepend Authtown::ViewMixin
54
+
55
+ secret = ENV.fetch("RODA_SECRET_KEY")
56
+ app.plugin(:sessions, secret:)
57
+
58
+ app.plugin :rodauth do
59
+ enable :login, :logout, :create_account, :remember, :reset_password
60
+ hmac_secret secret
61
+
62
+ prefix "/auth"
63
+
64
+ login_redirect account_landing_page
65
+ create_account_redirect account_landing_page
66
+ logout_redirect "/"
67
+
68
+ set_deadline_values? true # for remember, etc.
69
+ remember_deadline_interval days: 30 # TODO: why isn't this working?!
70
+ extend_remember_deadline? true
71
+
72
+ login_label "Email Address"
73
+ login_button "Sign In"
74
+
75
+ accounts_table :users
76
+ account_password_hash_column :password_hash
77
+
78
+ require_login_confirmation? false
79
+ require_password_confirmation? false
80
+
81
+ # Require passwords to have at least 8 characters
82
+ password_minimum_length 8
83
+
84
+ # Don't allow passwords to be too long, to prevent long password DoS attacks
85
+ password_maximum_length 64
86
+
87
+ reset_password_email_sent_redirect "/account/reset-link-sent"
88
+ reset_password_autologin? true
89
+ reset_password_redirect account_landing_page
90
+
91
+ before_create_account do
92
+ # Make sure timestamps get saved
93
+ account[:created_at] = account[:updated_at] = Time.now
94
+
95
+ account[:first_name] = param(:first_name)
96
+ end
97
+
98
+ after_login do
99
+ remember_login
100
+ end
101
+
102
+ instance_exec(&rodauth_config) if rodauth_config
103
+ end
104
+ end
105
+ end
106
+
107
+ # Register your builder:
108
+ config.builder Authtown::Builder
109
+ end
110
+ # rubocop:enable Metrics/BlockLength
metadata ADDED
@@ -0,0 +1,161 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: authtown
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Bridgetown Team
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-08-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bridgetown
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.3.0
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 1.3.0
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.0'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rodauth
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '2.30'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '2.30'
47
+ - !ruby/object:Gem::Dependency
48
+ name: bcrypt
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '3.1'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '3.1'
61
+ - !ruby/object:Gem::Dependency
62
+ name: mail
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '2.8'
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '2.8'
75
+ - !ruby/object:Gem::Dependency
76
+ name: bundler
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rake
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '13.0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '13.0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: rubocop-bridgetown
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: '0.3'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: '0.3'
117
+ description:
118
+ email: maintainers@bridgetownrb.com
119
+ executables: []
120
+ extensions: []
121
+ extra_rdoc_files: []
122
+ files:
123
+ - ".github/workflows/tests.yml"
124
+ - ".gitignore"
125
+ - ".rubocop.yml"
126
+ - CHANGELOG.md
127
+ - Gemfile
128
+ - LICENSE.txt
129
+ - README.md
130
+ - Rakefile
131
+ - authtown.gemspec
132
+ - bridgetown.automation.rb
133
+ - lib/authtown.rb
134
+ - lib/authtown/builder.rb
135
+ - lib/authtown/routes/rodauth.rb
136
+ - lib/authtown/version.rb
137
+ - lib/authtown/view_mixin.rb
138
+ homepage: https://github.com/bridgetownrb/authtown
139
+ licenses:
140
+ - MIT
141
+ metadata: {}
142
+ post_install_message:
143
+ rdoc_options: []
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '3.1'
151
+ required_rubygems_version: !ruby/object:Gem::Requirement
152
+ requirements:
153
+ - - ">="
154
+ - !ruby/object:Gem::Version
155
+ version: '0'
156
+ requirements: []
157
+ rubygems_version: 3.3.3
158
+ signing_key:
159
+ specification_version: 4
160
+ summary: Rodauth integration for Bridgetown
161
+ test_files: []