Skip to content

Initial commit of aws-actiondispatch-dynamodb #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*Issue #, if available:*

*Description of changes:*

By submitting this pull request, I confirm that my contribution is made under
the terms of the Apache 2.0 license.
85 changes: 85 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: CI

on:
push:
branches:
- main

pull_request:
branches:
- main

env:
ruby_version: 3.3

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ruby: [2.7, '3.0', 3.1, 3.2, 3.3, jruby-9.4]
rails: [7.1, 7.2, '8.0', main]

exclude:
# Rails 7.2 is Ruby >= 3.1
- rails: 7.2
ruby: 2.7
- rails: 7.2
ruby: 3.0
# Rails 8.0 is Ruby >= 3.2
- rails: '8.0'
ruby: 2.7
- rails: '8.0'
ruby: 3.0
- rails: '8.0'
ruby: 3.1
- rails: '8.0'
ruby: jruby-9.4
# Rails main is Ruby >= 3.2
- rails: main
ruby: 2.7
- rails: main
ruby: 3.0
- rails: main
ruby: 3.1
- rails: main
ruby: jruby-9.4

steps:
- uses: actions/checkout@v4

- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler-cache: true

- name: Install gems
run: bundle install
env:
BUNDLE_GEMFILE: gemfiles/rails-${{ matrix.rails }}.gemfile

- name: Test
run: bundle exec rake test
env:
BUNDLE_GEMFILE: gemfiles/rails-${{ matrix.rails }}.gemfile

rubocop:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ env.ruby_version }}

- name: Install gems
run: |
bundle config set --local with 'development'
bundle install

- name: Rubocop
run: bundle exec rake rubocop
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.idea/
Gemfile.lock
gemfiles/*.gemfile.lock

test/dummy/db/migrate
test/dummy/log/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "tasks/release"]
path = tasks/release
url = https://github.com/aws/aws-sdk-ruby-release-tools
16 changes: 16 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
AllCops:
NewCops: enable
TargetRubyVersion: 2.7
SuggestExtensions: false

Gemspec/RequireMFA:
Enabled: false

Metrics/BlockLength:
Exclude:
- 'spec/**/*.rb'

Naming/FileName:
Exclude:
- 'gemfiles/*.gemfile'
- 'lib/aws-actiondispatch-dynamodb.rb'
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Unreleased Changes
------------------

* Feature - Initial version of this gem.
25 changes: 25 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# frozen_string_literal: true

source 'https://rubygems.org'

gemspec

gem 'rake', require: false

group :development do
gem 'byebug', platforms: :ruby
gem 'rubocop'
end

group :test do
gem 'minitest-spec-rails'
end

group :docs do
gem 'yard'
gem 'yard-sitemap', '~> 1.0'
end

group :release do
gem 'octokit'
end
165 changes: 156 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,164 @@
## My Project
# ActionDispatch Session Storage with Amazon DynamoDB

TODO: Fill this README out!
[![Gem Version](https://badge.fury.io/rb/aws-actiondispatch-dynamodb-ruby.svg)](https://badge.fury.io/rb/aws-actiondispatch-dynamodb-ruby)
[![Build Status](https://github.com/aws/aws-actiondispatch-dynamodb-ruby/workflows/CI/badge.svg)](https://github.com/aws/aws-actiondispatch-dynamodb-ruby/actions)
[![Github forks](https://img.shields.io/github/forks/aws/aws-actiondispatch-dynamodb-ruby.svg)](https://github.com/aws/aws-actiondispatch-dynamodb-ruby/network)
[![Github stars](https://img.shields.io/github/stars/aws/aws-actiondispatch-dynamodb-ruby.svg)](https://github.com/aws/aws-actiondispatch-dynamodb-ruby/stargazers)

Be sure to:
This gem contains an
[ActionDispatch AbstractStore](https://api.rubyonrails.org/classes/ActionDispatch/Session/AbstractStore.html)
implementation that uses Amazon DynamoDB as a session store, allowing access
to sessions from other applications and devices.

* Change the title in this README
* Edit your repository description on GitHub
## Installation

## Security
Add this gem to your Rails project's Gemfile:

See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information.
```ruby
gem 'aws-sdk-rails', '~> 4'
gem 'aws-actiondispatch-dynamodb', '~> 0'
```

## License
Then run `bundle install`.

This project is licensed under the Apache-2.0 License.
This gem also brings in the following AWS gems:

* `aws-sessionstore-dynamodb` -> `aws-sdk-dynamodb`

You will have to ensure that you provide credentials for the SDK to use. See the
latest [AWS SDK for Ruby Docs](https://docs.aws.amazon.com/sdk-for-ruby/v3/api/index.html#Configuration)
for details.

If you're running your Rails application on Amazon EC2, the AWS SDK will
check Amazon EC2 instance metadata for credentials to load. Learn more:
[IAM Roles for Amazon EC2](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html)

## Usage

To use the session store, add or edit your
`config/initializers/session_store.rb` file:

```ruby
options = { table_name: '_your_app_session' }
Rails.application.config.session_store :dynamo_db_store, **options
```

You can now start your Rails application with DynamoDB session support.

**Note**: You will need a DynamoDB table to store your sessions. You can create
the table using the provided Rake tasks or ActiveRecord migration generator
after configuring.

## Configuration

You can configure the session store with code, ENV, or a YAML file, in this
order of precedence. To configure in code, you can directly pass options to your
`config/initializers/session_store.rb` file like so:

```ruby
options = {
table_name: 'your-table-name',
table_key: 'your-session-key',
dynamo_db_client: Aws::DynamoDB::Client.new(region: 'us-west-2')
}
Rails.application.config.session_store :dynamo_db_store, **options
```

The session store inherits from the
[`Rack::Session::Abstract::Persisted`](https://rubydoc.info/github/rack/rack-session/main/Rack/Session/Abstract/Persisted)
class, which also supports additional options (such as `:key`).

For more information about this feature and configuration options, see the
[Configuration](https://docs.aws.amazon.com/sdk-for-ruby/aws-sessionstore-dynamodb/api/Aws/SessionStore/DynamoDB/Configuration.html)
class and the
[GitHub repository](https://github.com/aws/aws-sessionstore-dynamodb-ruby).

### Configuration file generator

You can generate a configuration file for the session store using the following
command (--environment=<environment> is optional):

```bash
rails generate dynamo_db:session_store_config --environment=<Rails.env>
```

The session store configuration generator command will generate a YAML file
`config/aws_dynamo_db_session_store.yml` with default options. If provided an
environment, the file will be named
`config/aws_dynamo_db_session_store/<Rails.env>.yml`, which takes precedence
over the default file.

## Migration

### ActiveRecord Migration generator

You can generate a migration file for the session table using the following
command (<MigrationName> is optional):

```bash
rails generate dynamo_db:session_store_migration <MigrationName>
```

The session store migration generator command will generate a
migration file `db/migration/#{VERSION}_#{MIGRATION_NAME}.rb`.

The migration file will create and delete a table with default options. These
options can be changed prior to running the migration either by changing the
configuration in the initializer, editing the migration file, in ENV, or in the
config YAML file. These options are documented in the
[Table](https://docs.aws.amazon.com/sdk-for-ruby/aws-sessionstore-dynamodb/api/Aws/SessionStore/DynamoDB/Table.html)
class.

To create the table, run migrations as normal with:

```bash
rails db:migrate
```

To delete the table and rollback, run the following command:

```bash
rails db:migrate:down VERSION=<VERSION>
```

### Migration Rake tasks

If you are not using ActiveRecord, you can manage the table using the provided
Rake tasks:

```bash
rake dynamo_db:session_store:create_table
rake dynamo_db:session_store:delete_table
```

The rake tasks will create and delete a table with default options. These
options can be changed prior to running the task either by changing the
configuration in the initializer, in ENV, or in the config YAML file. These
options are documented in the
[Table](https://docs.aws.amazon.com/sdk-for-ruby/aws-sessionstore-dynamodb/api/Aws/SessionStore/DynamoDB/Table.html)
class.

## Cleaning old sessions

By default sessions do not expire. You can use `:max_age` and `:max_stale` to
configure the max age or stale period of a session.

You can use the DynamoDB
[Time to Live (TTL) feature](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html)
on the `expire_at` attribute to automatically delete expired items, saving you
the trouble of manually deleting them and reducing costs.

If you wish to delete old sessions based on creation age (invalidating valid
sessions) or if you want control over the garbage collection process, you can
use the provided Rake task:

```bash
rake dynamo_db:session_store:clean
```

The rake task will clean the table with default options. These options can be
changed prior to running the task either by changing the configuration in the
initializer, in ENV, or in the config YAML file. These options are documented in
the
[GarbageCollector](https://docs.aws.amazon.com/sdk-for-ruby/aws-sessionstore-dynamodb/api/Aws/SessionStore/DynamoDB/GarbageCollector.html)
class.
18 changes: 18 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

require 'rake/testtask'
require 'rubocop/rake_task'

Dir.glob('tasks/**/*.rake').each do |task_file|
load task_file
end

RuboCop::RakeTask.new

Rake::TestTask.new do |t|
t.libs << 'test'
t.pattern = 'test/**/*_test.rb'
t.warning = false
end

task 'release:test' => :test
1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0.1.0
20 changes: 20 additions & 0 deletions aws-actiondispatch-dynamodb.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

version = File.read(File.expand_path('VERSION', __dir__)).strip

Gem::Specification.new do |spec|
spec.name = 'aws-actiondispatch-dynamodb'
spec.version = version
spec.author = 'Amazon Web Services'
spec.email = ['[email protected]']
spec.summary = 'ActionDispatch integration with DynamoDB'
spec.description = 'Amazon Dynamo DB as an ActionDispatch session store'
spec.homepage = 'https://github.com/aws/aws-actiondispatch-dynamodb-ruby'
spec.license = 'Apache-2.0'
spec.files = Dir['LICENSE', 'CHANGELOG.md', 'VERSION', 'lib/**/*']

spec.add_dependency('actionpack', '>= 7.1.0')
spec.add_dependency('aws-sessionstore-dynamodb', '~> 3')

spec.required_ruby_version = '>= 2.7'
end
5 changes: 5 additions & 0 deletions gemfiles/rails-7.1.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

eval_gemfile '../Gemfile'

gem 'rails', '~> 7.1.0'
5 changes: 5 additions & 0 deletions gemfiles/rails-7.2.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

eval_gemfile '../Gemfile'

gem 'rails', '~> 7.2.0'
5 changes: 5 additions & 0 deletions gemfiles/rails-8.0.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

eval_gemfile '../Gemfile'

gem 'rails', '~> 8.0.0'
5 changes: 5 additions & 0 deletions gemfiles/rails-main.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

eval_gemfile '../Gemfile'

gem 'rails', github: 'rails/rails'
Loading