diff --git a/.gitignore b/.gitignore
index 9c94c05..69523bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,3 +35,4 @@
/config/master.key
postgres-data/
+.env
\ No newline at end of file
diff --git a/Gemfile b/Gemfile
index 1cadfa1..458d84d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -6,6 +6,8 @@ ruby "3.1.1"
# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem "rails", "~> 7.0.2", ">= 7.0.2.3"
+# gem "devise"
+
# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails]
gem "sprockets-rails"
@@ -27,6 +29,12 @@ gem "stimulus-rails"
# Build JSON APIs with ease [https://github.com/rails/jbuilder]
gem "jbuilder"
+gem "omniauth"
+gem "omniauth-discord"
+# gem "omniauth-rails_csrf_protection"
+
+gem "dotenv-rails"
+
# Use Redis adapter to run Action Cable in production
# gem "redis", "~> 4.0"
diff --git a/Gemfile.lock b/Gemfile.lock
index a779d30..04c9f97 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -88,9 +88,18 @@ GEM
irb (>= 1.3.6)
reline (>= 0.2.7)
digest (3.1.0)
+ dotenv (2.7.6)
+ dotenv-rails (2.7.6)
+ dotenv (= 2.7.6)
+ railties (>= 3.2)
erubi (1.10.0)
+ faraday (2.2.0)
+ faraday-net_http (~> 2.0)
+ ruby2_keywords (>= 0.0.4)
+ faraday-net_http (2.0.1)
globalid (1.0.0)
activesupport (>= 5.0)
+ hashie (5.0.0)
i18n (1.10.0)
concurrent-ruby (~> 1.0)
importmap-rails (1.0.3)
@@ -102,6 +111,7 @@ GEM
jbuilder (2.11.5)
actionview (>= 5.0.0)
activesupport (>= 5.0.0)
+ jwt (2.3.0)
loofah (2.16.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
@@ -113,6 +123,8 @@ GEM
mini_mime (1.1.2)
minitest (5.15.0)
msgpack (1.5.1)
+ multi_json (1.15.0)
+ multi_xml (0.6.0)
net-imap (0.2.3)
digest
net-protocol
@@ -130,11 +142,29 @@ GEM
nio4r (2.5.8)
nokogiri (1.13.3-x86_64-linux)
racc (~> 1.4)
+ oauth2 (1.4.9)
+ faraday (>= 0.17.3, < 3.0)
+ jwt (>= 1.0, < 3.0)
+ multi_json (~> 1.3)
+ multi_xml (~> 0.5)
+ rack (>= 1.2, < 3)
+ omniauth (2.0.4)
+ hashie (>= 3.4.6)
+ rack (>= 1.6.2, < 3)
+ rack-protection
+ omniauth-discord (1.0.2)
+ omniauth (~> 2.0.4)
+ omniauth-oauth2
+ omniauth-oauth2 (1.7.2)
+ oauth2 (~> 1.4)
+ omniauth (>= 1.9, < 3)
public_suffix (4.0.6)
puma (5.6.4)
nio4r (~> 2.0)
racc (1.6.0)
rack (2.2.3)
+ rack-protection (2.2.0)
+ rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (7.0.2.3)
@@ -168,6 +198,7 @@ GEM
reline (0.3.1)
io-console (~> 0.5)
rexml (3.2.5)
+ ruby2_keywords (0.0.5)
rubyzip (2.3.2)
selenium-webdriver (4.1.0)
childprocess (>= 0.5, < 5.0)
@@ -214,8 +245,11 @@ DEPENDENCIES
bootsnap
capybara
debug
+ dotenv-rails
importmap-rails
jbuilder
+ omniauth
+ omniauth-discord
puma (~> 5.0)
rails (~> 7.0.2, >= 7.0.2.3)
selenium-webdriver
diff --git a/app/controllers/discord_users_controller.rb b/app/controllers/discord_users_controller.rb
new file mode 100644
index 0000000..7b98a64
--- /dev/null
+++ b/app/controllers/discord_users_controller.rb
@@ -0,0 +1,2 @@
+class DiscordUsersController < ApplicationController
+end
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
new file mode 100644
index 0000000..16d11b5
--- /dev/null
+++ b/app/controllers/sessions_controller.rb
@@ -0,0 +1,2 @@
+class SessionsController < ApplicationController
+end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
new file mode 100644
index 0000000..448eeba
--- /dev/null
+++ b/app/controllers/users_controller.rb
@@ -0,0 +1,70 @@
+class UsersController < ApplicationController
+ before_action :set_user, only: %i[ show edit update destroy ]
+
+ # GET /users or /users.json
+ def index
+ @users = User.all
+ end
+
+ # GET /users/1 or /users/1.json
+ def show
+ end
+
+ # GET /users/new
+ def new
+ @user = User.new
+ end
+
+ # GET /users/1/edit
+ def edit
+ end
+
+ # POST /users or /users.json
+ def create
+ @user = User.new(user_params)
+
+ respond_to do |format|
+ if @user.save
+ format.html { redirect_to user_url(@user), notice: "User was successfully created." }
+ format.json { render :show, status: :created, location: @user }
+ else
+ format.html { render :new, status: :unprocessable_entity }
+ format.json { render json: @user.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ # PATCH/PUT /users/1 or /users/1.json
+ def update
+ respond_to do |format|
+ if @user.update(user_params)
+ format.html { redirect_to user_url(@user), notice: "User was successfully updated." }
+ format.json { render :show, status: :ok, location: @user }
+ else
+ format.html { render :edit, status: :unprocessable_entity }
+ format.json { render json: @user.errors, status: :unprocessable_entity }
+ end
+ end
+ end
+
+ # DELETE /users/1 or /users/1.json
+ def destroy
+ @user.destroy
+
+ respond_to do |format|
+ format.html { redirect_to users_url, notice: "User was successfully destroyed." }
+ format.json { head :no_content }
+ end
+ end
+
+ private
+ # Use callbacks to share common setup or constraints between actions.
+ def set_user
+ @user = User.find(params[:id])
+ end
+
+ # Only allow a list of trusted parameters through.
+ def user_params
+ params.require(:user).permit(:provider, :uid, :border)
+ end
+end
diff --git a/app/helpers/discord_users_helper.rb b/app/helpers/discord_users_helper.rb
new file mode 100644
index 0000000..14ab233
--- /dev/null
+++ b/app/helpers/discord_users_helper.rb
@@ -0,0 +1,2 @@
+module DiscordUsersHelper
+end
diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb
new file mode 100644
index 0000000..309f8b2
--- /dev/null
+++ b/app/helpers/sessions_helper.rb
@@ -0,0 +1,2 @@
+module SessionsHelper
+end
diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb
new file mode 100644
index 0000000..2310a24
--- /dev/null
+++ b/app/helpers/users_helper.rb
@@ -0,0 +1,2 @@
+module UsersHelper
+end
diff --git a/app/models/discord.rb b/app/models/discord.rb
new file mode 100644
index 0000000..89469d1
--- /dev/null
+++ b/app/models/discord.rb
@@ -0,0 +1,4 @@
+class DiscordUser < ApplicationRecord
+ attr_accessible :discord_id, :username, :discriminator, :avatar
+ validates :discord_id, :uniqueness => true
+end
diff --git a/app/models/user.rb b/app/models/user.rb
new file mode 100644
index 0000000..379658a
--- /dev/null
+++ b/app/models/user.rb
@@ -0,0 +1,2 @@
+class User < ApplicationRecord
+end
diff --git a/app/views/users/_form.html.erb b/app/views/users/_form.html.erb
new file mode 100644
index 0000000..7057463
--- /dev/null
+++ b/app/views/users/_form.html.erb
@@ -0,0 +1,32 @@
+<%= form_with(model: user) do |form| %>
+ <% if user.errors.any? %>
+
+
<%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:
+
+
+ <% user.errors.each do |error| %>
+ - <%= error.full_message %>
+ <% end %>
+
+
+ <% end %>
+
+
+ <%= form.label :provider, style: "display: block" %>
+ <%= form.text_field :provider %>
+
+
+
+ <%= form.label :uid, style: "display: block" %>
+ <%= form.text_field :uid %>
+
+
+
+ <%= form.label :border, style: "display: block" %>
+ <%= form.text_field :border %>
+
+
+
+ <%= form.submit %>
+
+<% end %>
diff --git a/app/views/users/_user.html.erb b/app/views/users/_user.html.erb
new file mode 100644
index 0000000..817fed3
--- /dev/null
+++ b/app/views/users/_user.html.erb
@@ -0,0 +1,17 @@
+
+
+ Provider:
+ <%= user.provider %>
+
+
+
+ Uid:
+ <%= user.uid %>
+
+
+
+ Border:
+ <%= user.border %>
+
+
+
diff --git a/app/views/users/_user.json.jbuilder b/app/views/users/_user.json.jbuilder
new file mode 100644
index 0000000..80e7628
--- /dev/null
+++ b/app/views/users/_user.json.jbuilder
@@ -0,0 +1,2 @@
+json.extract! user, :id, :provider, :uid, :border, :created_at, :updated_at
+json.url user_url(user, format: :json)
diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb
new file mode 100644
index 0000000..9dda632
--- /dev/null
+++ b/app/views/users/edit.html.erb
@@ -0,0 +1,10 @@
+Editing user
+
+<%= render "form", user: @user %>
+
+
+
+
+ <%= link_to "Show this user", @user %> |
+ <%= link_to "Back to users", users_path %>
+
diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb
new file mode 100644
index 0000000..fe4dd5c
--- /dev/null
+++ b/app/views/users/index.html.erb
@@ -0,0 +1,14 @@
+<%= notice %>
+
+Users
+
+
+ <% @users.each do |user| %>
+ <%= render user %>
+
+ <%= link_to "Show this user", user %>
+
+ <% end %>
+
+
+<%= link_to "New user", new_user_path %>
diff --git a/app/views/users/index.json.jbuilder b/app/views/users/index.json.jbuilder
new file mode 100644
index 0000000..98788da
--- /dev/null
+++ b/app/views/users/index.json.jbuilder
@@ -0,0 +1 @@
+json.array! @users, partial: "users/user", as: :user
diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb
new file mode 100644
index 0000000..eedbd83
--- /dev/null
+++ b/app/views/users/new.html.erb
@@ -0,0 +1,9 @@
+New user
+
+<%= render "form", user: @user %>
+
+
+
+
+ <%= link_to "Back to users", users_path %>
+
diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb
new file mode 100644
index 0000000..673fae2
--- /dev/null
+++ b/app/views/users/show.html.erb
@@ -0,0 +1,10 @@
+<%= notice %>
+
+<%= render @user %>
+
+
+ <%= link_to "Edit this user", edit_user_path(@user) %> |
+ <%= link_to "Back to users", users_path %>
+
+ <%= button_to "Destroy this user", @user, method: :delete %>
+
diff --git a/app/views/users/show.json.jbuilder b/app/views/users/show.json.jbuilder
new file mode 100644
index 0000000..ff40bb9
--- /dev/null
+++ b/app/views/users/show.json.jbuilder
@@ -0,0 +1 @@
+json.partial! "users/user", user: @user
diff --git a/config/application.rb b/config/application.rb
index 64da099..2945b0e 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -6,11 +6,15 @@ require "rails/all"
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)
+Dotenv::Railtie.load
+
module Borders
class Application < Rails::Application
# Initialize configuration defaults for originally generated Rails version.
config.load_defaults 7.0
+ config.hosts << "dev.j4.pm"
+
# Configuration for the application, engines, and railties goes here.
#
# These settings can be overridden in specific environments using the files
@@ -18,5 +22,15 @@ module Borders
#
# config.time_zone = "Central Time (US & Canada)"
# config.eager_load_paths << Rails.root.join("extras")
+
+ config.session_store :cookie_store, key: '_interslice_session'
+ config.middleware.use ActionDispatch::Cookies
+ config.middleware.use ActionDispatch::Session::CookieStore, config.session_options
+
+ config.middleware.use OmniAuth::Builder do
+ provider :discord, ENV['DISCORD_CLIENT_ID'], ENV['DISCORD_CLIENT_SECRET'], scope: 'identify'
+ end
+
+ OmniAuth.config.logger = Rails.logger
end
end
diff --git a/config/routes.rb b/config/routes.rb
index 262ffd5..86b5b00 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,6 +1,12 @@
Rails.application.routes.draw do
+ resources :users
+ resources :discord_users
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
# Defines the root path route ("/")
# root "articles#index"
+ match "/login" => "sessions#new", :as => :login, via: [:get, :post]
+ match "/auth/:provider/callback" => "sessions#create", via: [:post]
+ match "/logout" => "sessions#destroy", :as => :logout, via: [:post]
+ match "/auth/failure" => "sessions#failure", via: [:get]
end
diff --git a/db/migrate/20220409220708_create_discordusers.rb b/db/migrate/20220409220708_create_discordusers.rb
new file mode 100644
index 0000000..6941c33
--- /dev/null
+++ b/db/migrate/20220409220708_create_discordusers.rb
@@ -0,0 +1,12 @@
+class CreateDiscordusers < ActiveRecord::Migration[7.0]
+ def change
+ create_table :discord_users do |t|
+ t.string :discord_id
+ t.string :username
+ t.string :discriminator
+ t.string :avatar
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/migrate/20220410011426_create_users.rb b/db/migrate/20220410011426_create_users.rb
new file mode 100644
index 0000000..0b2dbc8
--- /dev/null
+++ b/db/migrate/20220410011426_create_users.rb
@@ -0,0 +1,11 @@
+class CreateUsers < ActiveRecord::Migration[7.0]
+ def change
+ create_table :users do |t|
+ t.string :provider
+ t.string :uid
+ t.string :border
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
new file mode 100644
index 0000000..5ae4afe
--- /dev/null
+++ b/db/schema.rb
@@ -0,0 +1,30 @@
+# This file is auto-generated from the current state of the database. Instead
+# of editing this file, please use the migrations feature of Active Record to
+# incrementally modify your database, and then regenerate this schema definition.
+#
+# This file is the source Rails uses to define your schema when running `bin/rails
+# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
+# be faster and is potentially less error prone than running all of your
+# migrations from scratch. Old migrations may fail to apply correctly if those
+# migrations use external dependencies or application code.
+#
+# It's strongly recommended that you check this file into your version control system.
+
+ActiveRecord::Schema[7.0].define(version: 2022_04_09_220708) do
+ create_table "discord_users", force: :cascade do |t|
+ t.string "discord_id"
+ t.string "username"
+ t.string "discriminator"
+ t.string "avatar"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
+ create_table "users", force: :cascade do |t|
+ t.string "provider"
+ t.string "uid"
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
+end
diff --git a/test/controllers/discord_users_controller_test.rb b/test/controllers/discord_users_controller_test.rb
new file mode 100644
index 0000000..3bf2faa
--- /dev/null
+++ b/test/controllers/discord_users_controller_test.rb
@@ -0,0 +1,7 @@
+require "test_helper"
+
+class DiscordUsersControllerTest < ActionDispatch::IntegrationTest
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/controllers/sessions_controller_test.rb b/test/controllers/sessions_controller_test.rb
new file mode 100644
index 0000000..e5da4b3
--- /dev/null
+++ b/test/controllers/sessions_controller_test.rb
@@ -0,0 +1,7 @@
+require "test_helper"
+
+class SessionsControllerTest < ActionDispatch::IntegrationTest
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb
new file mode 100644
index 0000000..1c6ba6b
--- /dev/null
+++ b/test/controllers/users_controller_test.rb
@@ -0,0 +1,48 @@
+require "test_helper"
+
+class UsersControllerTest < ActionDispatch::IntegrationTest
+ setup do
+ @user = users(:one)
+ end
+
+ test "should get index" do
+ get users_url
+ assert_response :success
+ end
+
+ test "should get new" do
+ get new_user_url
+ assert_response :success
+ end
+
+ test "should create user" do
+ assert_difference("User.count") do
+ post users_url, params: { user: { border: @user.border, provider: @user.provider, uid: @user.uid } }
+ end
+
+ assert_redirected_to user_url(User.last)
+ end
+
+ test "should show user" do
+ get user_url(@user)
+ assert_response :success
+ end
+
+ test "should get edit" do
+ get edit_user_url(@user)
+ assert_response :success
+ end
+
+ test "should update user" do
+ patch user_url(@user), params: { user: { border: @user.border, provider: @user.provider, uid: @user.uid } }
+ assert_redirected_to user_url(@user)
+ end
+
+ test "should destroy user" do
+ assert_difference("User.count", -1) do
+ delete user_url(@user)
+ end
+
+ assert_redirected_to users_url
+ end
+end
diff --git a/test/fixtures/identities.yml b/test/fixtures/identities.yml
new file mode 100644
index 0000000..3022067
--- /dev/null
+++ b/test/fixtures/identities.yml
@@ -0,0 +1,13 @@
+# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+ id: MyString
+ username: MyString
+ discriminator: MyString
+ avatar: MyString
+
+two:
+ id: MyString
+ username: MyString
+ discriminator: MyString
+ avatar: MyString
diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml
new file mode 100644
index 0000000..8cfb08c
--- /dev/null
+++ b/test/fixtures/users.yml
@@ -0,0 +1,11 @@
+# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+one:
+ provider: MyString
+ uid: MyString
+ border: MyString
+
+two:
+ provider: MyString
+ uid: MyString
+ border: MyString
diff --git a/test/models/identity_test.rb b/test/models/identity_test.rb
new file mode 100644
index 0000000..da7146f
--- /dev/null
+++ b/test/models/identity_test.rb
@@ -0,0 +1,7 @@
+require "test_helper"
+
+class IdentityTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/models/user_test.rb b/test/models/user_test.rb
new file mode 100644
index 0000000..5c07f49
--- /dev/null
+++ b/test/models/user_test.rb
@@ -0,0 +1,7 @@
+require "test_helper"
+
+class UserTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/system/users_test.rb b/test/system/users_test.rb
new file mode 100644
index 0000000..8eab9f5
--- /dev/null
+++ b/test/system/users_test.rb
@@ -0,0 +1,45 @@
+require "application_system_test_case"
+
+class UsersTest < ApplicationSystemTestCase
+ setup do
+ @user = users(:one)
+ end
+
+ test "visiting the index" do
+ visit users_url
+ assert_selector "h1", text: "Users"
+ end
+
+ test "should create user" do
+ visit users_url
+ click_on "New user"
+
+ fill_in "Border", with: @user.border
+ fill_in "Provider", with: @user.provider
+ fill_in "Uid", with: @user.uid
+ click_on "Create User"
+
+ assert_text "User was successfully created"
+ click_on "Back"
+ end
+
+ test "should update User" do
+ visit user_url(@user)
+ click_on "Edit this user", match: :first
+
+ fill_in "Border", with: @user.border
+ fill_in "Provider", with: @user.provider
+ fill_in "Uid", with: @user.uid
+ click_on "Update User"
+
+ assert_text "User was successfully updated"
+ click_on "Back"
+ end
+
+ test "should destroy User" do
+ visit user_url(@user)
+ click_on "Destroy this user", match: :first
+
+ assert_text "User was successfully destroyed"
+ end
+end