Add basic invitations
This commit is contained in:
parent
18df8fe449
commit
d7fbda0855
@ -12,7 +12,7 @@ credentials, invites, donations, etc..
|
|||||||
* [x] View LDAP users as admin
|
* [x] View LDAP users as admin
|
||||||
* [ ] List my donations
|
* [ ] List my donations
|
||||||
* [ ] Invite new users from your account
|
* [ ] Invite new users from your account
|
||||||
* [ ] Sign up for a new account via invite
|
* [ ] Sign up for a new account via invitation
|
||||||
* [ ] Sign up for a new account by donating upfront
|
* [ ] Sign up for a new account by donating upfront
|
||||||
* [ ] Sign up for a new account via proving contributions (via cryptographic signature)
|
* [ ] Sign up for a new account via proving contributions (via cryptographic signature)
|
||||||
* [ ] ...
|
* [ ] ...
|
||||||
|
33
app/controllers/invitations_controller.rb
Normal file
33
app/controllers/invitations_controller.rb
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
class InvitationsController < ApplicationController
|
||||||
|
before_action :require_user_signed_in
|
||||||
|
|
||||||
|
# GET /invitations
|
||||||
|
def index
|
||||||
|
@invitations = current_user.invitations
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST /invitations
|
||||||
|
def create
|
||||||
|
@invitation = Invitation.new(user: current_user)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
if @invitation.save
|
||||||
|
format.html { redirect_to @invitation, notice: 'Invitation was successfully created.' }
|
||||||
|
format.json { render :show, status: :created, location: @invitation }
|
||||||
|
else
|
||||||
|
format.html { render :new }
|
||||||
|
format.json { render json: @invitation.errors, status: :unprocessable_entity }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# DELETE /invitations/1
|
||||||
|
def destroy
|
||||||
|
@invitation = current_user.invitations.find(params[:id])
|
||||||
|
@invitation.destroy
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to invitations_url }
|
||||||
|
format.json { head :no_content }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
2
app/helpers/invitations_helper.rb
Normal file
2
app/helpers/invitations_helper.rb
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
module InvitationsHelper
|
||||||
|
end
|
14
app/models/invitation.rb
Normal file
14
app/models/invitation.rb
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
class Invitation < ApplicationRecord
|
||||||
|
# Relations
|
||||||
|
belongs_to :user
|
||||||
|
|
||||||
|
validates_presence_of :user
|
||||||
|
|
||||||
|
before_create :generate_token
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def generate_token
|
||||||
|
self.token = SecureRandom.hex(8)
|
||||||
|
end
|
||||||
|
end
|
@ -1,4 +1,7 @@
|
|||||||
class User < ApplicationRecord
|
class User < ApplicationRecord
|
||||||
|
# Relations
|
||||||
|
has_many :invitations, dependent: :destroy
|
||||||
|
|
||||||
# Include default devise modules. Others available are:
|
# Include default devise modules. Others available are:
|
||||||
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
|
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
|
||||||
devise :ldap_authenticatable,
|
devise :ldap_authenticatable,
|
||||||
|
23
app/views/invitations/index.html.erb
Normal file
23
app/views/invitations/index.html.erb
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<section>
|
||||||
|
<h2>Invitations</h2>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Token</th>
|
||||||
|
<th>Created at</th>
|
||||||
|
<th colspan="3"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
|
||||||
|
<tbody>
|
||||||
|
<% @invitations.each do |invitation| %>
|
||||||
|
<tr>
|
||||||
|
<td><%= invitation.token %></td>
|
||||||
|
<td><%= invitation.created_at %></td>
|
||||||
|
<td><%= link_to 'Delete', invitation, method: :delete, data: { confirm: 'Are you sure?' } %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</section>
|
@ -1,11 +1,13 @@
|
|||||||
Rails.application.routes.draw do
|
Rails.application.routes.draw do
|
||||||
devise_for :users
|
devise_for :users
|
||||||
|
|
||||||
|
get 'welcome', to: 'welcome#index'
|
||||||
|
get 'check_your_email', to: 'welcome#check_your_email'
|
||||||
|
|
||||||
get 'settings', to: 'settings#index'
|
get 'settings', to: 'settings#index'
|
||||||
post 'settings_reset_password', to: 'settings#reset_password'
|
post 'settings_reset_password', to: 'settings#reset_password'
|
||||||
|
|
||||||
get 'welcome', to: 'welcome#index'
|
resources :invitations, only: ['index', 'create', 'destroy']
|
||||||
get 'check_your_email', to: 'welcome#check_your_email'
|
|
||||||
|
|
||||||
namespace :admin do
|
namespace :admin do
|
||||||
root to: 'dashboard#index'
|
root to: 'dashboard#index'
|
||||||
|
12
db/migrate/20201130132533_create_invitations.rb
Normal file
12
db/migrate/20201130132533_create_invitations.rb
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
class CreateInvitations < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
create_table :invitations do |t|
|
||||||
|
t.string :token
|
||||||
|
t.integer :user_id
|
||||||
|
t.integer :invited_user_id
|
||||||
|
t.datetime :used_at
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
11
db/schema.rb
11
db/schema.rb
@ -10,7 +10,16 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2020_11_09_090739) do
|
ActiveRecord::Schema.define(version: 2020_11_30_132533) do
|
||||||
|
|
||||||
|
create_table "invitations", force: :cascade do |t|
|
||||||
|
t.string "token"
|
||||||
|
t.integer "user_id"
|
||||||
|
t.integer "invited_user_id"
|
||||||
|
t.datetime "used_at"
|
||||||
|
t.datetime "created_at", precision: 6, null: false
|
||||||
|
t.datetime "updated_at", precision: 6, null: false
|
||||||
|
end
|
||||||
|
|
||||||
create_table "users", force: :cascade do |t|
|
create_table "users", force: :cascade do |t|
|
||||||
t.string "cn"
|
t.string "cn"
|
||||||
|
13
spec/fixtures/invitations.yml
vendored
Normal file
13
spec/fixtures/invitations.yml
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||||
|
|
||||||
|
one:
|
||||||
|
token: fedcba654321
|
||||||
|
user_id: 1
|
||||||
|
invited_user_id: nil
|
||||||
|
used_at: nil
|
||||||
|
|
||||||
|
two:
|
||||||
|
token: abcdef123456
|
||||||
|
user_id: 1
|
||||||
|
invited_user_id: nil
|
||||||
|
used_at: nil
|
15
spec/helpers/invitations_helper_spec.rb
Normal file
15
spec/helpers/invitations_helper_spec.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
# Specs in this file have access to a helper object that includes
|
||||||
|
# the InvitationsHelper. For example:
|
||||||
|
#
|
||||||
|
# describe InvitationsHelper do
|
||||||
|
# describe "string concat" do
|
||||||
|
# it "concats two strings with spaces" do
|
||||||
|
# expect(helper.concat_strings("this","that")).to eq("this that")
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
RSpec.describe InvitationsHelper, type: :helper do
|
||||||
|
pending "add some examples to (or delete) #{__FILE__}"
|
||||||
|
end
|
22
spec/models/invitation_spec.rb
Normal file
22
spec/models/invitation_spec.rb
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Invitation, type: :model do
|
||||||
|
let(:user) { build :user }
|
||||||
|
|
||||||
|
describe "tokens" do
|
||||||
|
it "requires a user" do
|
||||||
|
expect { Invitation.create! }.to raise_error(ActiveRecord::RecordInvalid)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "generates a random token when created" do
|
||||||
|
invitation = Invitation.new(user: user)
|
||||||
|
invitation.save!
|
||||||
|
token = invitation.token
|
||||||
|
expect(token).to be_a(String)
|
||||||
|
expect(token.length).to eq(16)
|
||||||
|
|
||||||
|
invitation_2 = Invitation.create(user: user)
|
||||||
|
expect(token).not_to eq(invitation_2.token)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
x
Reference in New Issue
Block a user