Merge branch 'invites' of github.com:diaspora/diaspora into invites
This commit is contained in:
commit
9bfb213465
12 changed files with 180 additions and 4 deletions
2
Gemfile
2
Gemfile
|
|
@ -6,7 +6,7 @@ gem 'bundler', '>= 1.0.0'
|
|||
#Security
|
||||
gem 'devise', '1.1.2'
|
||||
gem 'devise-mongo_mapper', :git => 'git://github.com/collectiveidea/devise-mongo_mapper'
|
||||
|
||||
gem 'devise_invitable', '~> 0.3.4'
|
||||
#Mongo
|
||||
gem 'mongo_mapper', :branch => 'rails3', :git => 'http://github.com/jnunemaker/mongomapper.git'
|
||||
gem 'bson_ext', '1.1'
|
||||
|
|
|
|||
|
|
@ -135,6 +135,8 @@ GEM
|
|||
devise (1.1.2)
|
||||
bcrypt-ruby (~> 2.1.2)
|
||||
warden (~> 0.10.7)
|
||||
devise_invitable (0.3.4)
|
||||
devise (~> 1.1.0)
|
||||
diff-lcs (1.1.2)
|
||||
em-websocket (0.1.4)
|
||||
addressable (>= 2.1.1)
|
||||
|
|
@ -269,6 +271,7 @@ DEPENDENCIES
|
|||
database_cleaner
|
||||
devise (= 1.1.2)
|
||||
devise-mongo_mapper!
|
||||
devise_invitable (~> 0.3.4)
|
||||
em-http-request!
|
||||
em-websocket
|
||||
factory_girl_rails
|
||||
|
|
|
|||
26
app/controllers/invitations_controller.rb
Normal file
26
app/controllers/invitations_controller.rb
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
class InvitationsController < Devise::InvitationsController
|
||||
def update
|
||||
puts params.inspect
|
||||
begin
|
||||
puts params["user"]["invitation_token"]
|
||||
user = User.find_by_invitation_token(params["user"]["invitation_token"])
|
||||
|
||||
puts user.inspect
|
||||
user.accept_invitation!(params["user"])
|
||||
rescue MongoMapper::DocumentNotValid => e
|
||||
puts "Doc Not VALID"
|
||||
user = nil
|
||||
flash[:error] = e.message
|
||||
end
|
||||
if user
|
||||
flash[:notice] = I18n.t 'registrations.create.success'
|
||||
sign_in_and_redirect(:user, user)
|
||||
else
|
||||
redirect_to new_user_registration_path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -7,6 +7,16 @@ require File.join(Rails.root, 'lib/diaspora/user/querying')
|
|||
require File.join(Rails.root, 'lib/diaspora/user/receiving')
|
||||
require File.join(Rails.root, 'lib/salmon/salmon')
|
||||
|
||||
class InvitedUserValidator < ActiveModel::Validator
|
||||
def validate(document)
|
||||
unless document.invitation_token
|
||||
unless document.person
|
||||
document.errors[:base] << "Unless you are being invited, you must have a person"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class User
|
||||
include MongoMapper::Document
|
||||
plugin MongoMapper::Devise
|
||||
|
|
@ -16,11 +26,13 @@ class User
|
|||
include Encryptor::Private
|
||||
QUEUE = MessageHandler.new
|
||||
|
||||
devise :database_authenticatable, :registerable,
|
||||
devise :invitable, :database_authenticatable, :registerable,
|
||||
:recoverable, :rememberable, :trackable, :validatable
|
||||
key :username, :unique => true
|
||||
key :serialized_private_key, String
|
||||
|
||||
key :invitation_token, String
|
||||
key :invitation_sent_at, DateTime
|
||||
key :friend_ids, Array
|
||||
key :pending_request_ids, Array
|
||||
key :visible_post_ids, Array
|
||||
|
|
@ -38,6 +50,7 @@ class User
|
|||
after_create :seed_aspects
|
||||
|
||||
before_validation :downcase_username, :on => :create
|
||||
validates_with InvitedUserValidator
|
||||
|
||||
def self.find_for_authentication(conditions={})
|
||||
if conditions[:username] =~ /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i # email regex
|
||||
|
|
@ -252,6 +265,27 @@ class User
|
|||
end
|
||||
|
||||
###Helpers############
|
||||
|
||||
def accept_invitation!( opts = {} )
|
||||
if self.invited?
|
||||
self.username = opts[:username]
|
||||
self.password = opts[:password]
|
||||
self.password_confirmation = opts[:password_confirmation]
|
||||
opts[:person][:diaspora_handle] = "#{opts[:username]}@#{APP_CONFIG[:terse_pod_url]}"
|
||||
opts[:person][:url] = APP_CONFIG[:pod_url]
|
||||
|
||||
opts[:serialized_private_key] = User.generate_key
|
||||
self.serialized_private_key = opts[:serialized_private_key]
|
||||
opts[:person][:serialized_public_key] = opts[:serialized_private_key].public_key
|
||||
|
||||
person_hash = opts.delete(:person)
|
||||
self.person = Person.create(person_hash)
|
||||
self.person.save
|
||||
self.save
|
||||
self
|
||||
end
|
||||
end
|
||||
|
||||
def self.instantiate!( opts = {} )
|
||||
opts[:person][:diaspora_handle] = "#{opts[:username]}@#{APP_CONFIG[:terse_pod_url]}"
|
||||
opts[:person][:url] = APP_CONFIG[:pod_url]
|
||||
|
|
|
|||
25
app/views/invitations/edit.html.haml
Normal file
25
app/views/invitations/edit.html.haml
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
= image_tag "http://needcoffee.cachefly.net/needcoffee/uploads/2009/02/predator-arnold-schwarzenegger.jpg"
|
||||
|
||||
= form_for(resource, :as => resource_name, :url => invitation_path(resource_name), :html => {:method => :put }) do |f|
|
||||
%p
|
||||
= f.label :username
|
||||
= f.text_field :username
|
||||
%p
|
||||
= f.label :password
|
||||
= f.password_field :password
|
||||
%p
|
||||
= f.label :password_confirmation
|
||||
= f.password_field :password_confirmation
|
||||
|
||||
= f.fields_for :person do |p|
|
||||
= p.fields_for :profile do |pr|
|
||||
%p
|
||||
= pr.label :first_name
|
||||
= pr.text_field :first_name
|
||||
%p
|
||||
= pr.label :last_name
|
||||
= pr.text_field :last_name
|
||||
|
||||
= f.hidden_field :invitation_token
|
||||
= f.submit 'sign_up'
|
||||
= render :partial => "devise/shared/links"
|
||||
|
|
@ -22,6 +22,5 @@
|
|||
%p
|
||||
= pr.label :last_name
|
||||
= pr.text_field :last_name
|
||||
|
||||
= f.submit t('.sign_up')
|
||||
= render :partial => "devise/shared/links"
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
|
||||
%h2 Profile
|
||||
= link_to new_user_invitation_path(current_user)
|
||||
|
||||
= form_for @user do |f|
|
||||
= f.error_messages
|
||||
|
|
|
|||
|
|
@ -44,6 +44,11 @@ Devise.setup do |config|
|
|||
# Setup a pepper to generate the encrypted password.
|
||||
config.pepper = "065eb8798b181ff0ea2c5c16aee0ff8b70e04e2ee6bd6e08b49da46924223e39127d5335e466207d42bf2a045c12be5f90e92012a4f05f7fc6d9f3c875f4c95b"
|
||||
|
||||
# ==> Configuration for :invitable
|
||||
# Time interval where the invitation token is valid (default: 0).
|
||||
# If invite_for is 0 or nil, the invitation will never expire.
|
||||
# config.invite_for = 2.weeks
|
||||
|
||||
# ==> Configuration for :confirmable
|
||||
# The time you want to give your user to confirm his account. During this time
|
||||
# he will be able to access your application without confirming. Default is nil.
|
||||
|
|
|
|||
39
config/locales/devise.en.yml
Normal file
39
config/locales/devise.en.yml
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
en:
|
||||
errors:
|
||||
messages:
|
||||
not_found: "not found"
|
||||
already_confirmed: "was already confirmed"
|
||||
not_locked: "was not locked"
|
||||
|
||||
devise:
|
||||
failure:
|
||||
unauthenticated: 'You need to sign in or sign up before continuing.'
|
||||
unconfirmed: 'You have to confirm your account before continuing.'
|
||||
locked: 'Your account is locked.'
|
||||
invalid: 'Invalid email or password.'
|
||||
invalid_token: 'Invalid authentication token.'
|
||||
timeout: 'Your session expired, please sign in again to continue.'
|
||||
inactive: 'Your account was not activated yet.'
|
||||
sessions:
|
||||
signed_in: 'Signed in successfully.'
|
||||
signed_out: 'Signed out successfully.'
|
||||
passwords:
|
||||
send_instructions: 'You will receive an email with instructions about how to reset your password in a few minutes.'
|
||||
updated: 'Your password was changed successfully. You are now signed in.'
|
||||
confirmations:
|
||||
send_instructions: 'You will receive an email with instructions about how to confirm your account in a few minutes.'
|
||||
confirmed: 'Your account was successfully confirmed. You are now signed in.'
|
||||
registrations:
|
||||
signed_up: 'You have signed up successfully. If enabled, a confirmation was sent to your e-mail.'
|
||||
updated: 'You updated your account successfully.'
|
||||
destroyed: 'Bye! Your account was successfully cancelled. We hope to see you again soon.'
|
||||
unlocks:
|
||||
send_instructions: 'You will receive an email with instructions about how to unlock your account in a few minutes.'
|
||||
unlocked: 'Your account was successfully unlocked. You are now signed in.'
|
||||
mailer:
|
||||
confirmation_instructions:
|
||||
subject: 'Confirmation instructions'
|
||||
reset_password_instructions:
|
||||
subject: 'Reset password instructions'
|
||||
unlock_instructions:
|
||||
subject: 'Unlock Instructions'
|
||||
8
config/locales/devise_invitable.en.yml
Normal file
8
config/locales/devise_invitable.en.yml
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
en:
|
||||
devise:
|
||||
invitations:
|
||||
send_instructions: 'An email with instructions about how to set the password has been sent.'
|
||||
updated: 'Your password was set successfully. You are now signed in.'
|
||||
mailer:
|
||||
invitiation:
|
||||
subject: 'Invitation'
|
||||
|
|
@ -11,7 +11,8 @@ Diaspora::Application.routes.draw do
|
|||
resources :albums
|
||||
|
||||
devise_for :users, :controllers => {:registrations => "registrations",
|
||||
:password => "devise/passwords"}
|
||||
:password => "devise/passwords",
|
||||
:invitations => "invitations"}
|
||||
# added public route to user
|
||||
match 'public/:username', :to => 'users#public'
|
||||
match 'users/export', :to => 'users#export'
|
||||
|
|
|
|||
35
spec/models/user/invite_spec.rb
Normal file
35
spec/models/user/invite_spec.rb
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe User do
|
||||
let!(:invited_user) { create_user_with_invitation("abc")}
|
||||
|
||||
context "the acceptance of an invitation" do
|
||||
it "should create the person with the passed in params" do
|
||||
Person.count.should be 0
|
||||
u = invited_user.accept_invitation!(:invitation_token => "abc",
|
||||
:username => "user",
|
||||
:password => "secret",
|
||||
:password_confirmation => "secret",
|
||||
:person => {:profile => {:first_name => "Bob",
|
||||
:last_name => "Smith"}} )
|
||||
Person.count.should be 1
|
||||
u.person.profile.first_name.should == "Bob"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
def create_user_with_invitation(invitation_token, attributes={})
|
||||
user = User.new({:password => nil, :password_confirmation => nil}.update(attributes))
|
||||
#puts user.inspect
|
||||
#user.skip_confirmation!
|
||||
user.invitation_token = invitation_token
|
||||
user.invitation_sent_at = Time.now.utc
|
||||
user.save(:validate => false)
|
||||
user
|
||||
end
|
||||
Loading…
Reference in a new issue