diff --git a/app/controllers/invitations_controller.rb b/app/controllers/invitations_controller.rb new file mode 100644 index 000000000..d4f68c197 --- /dev/null +++ b/app/controllers/invitations_controller.rb @@ -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 diff --git a/app/models/user.rb b/app/models/user.rb index 48366d890..cab054b64 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -7,6 +7,16 @@ require File.expand_path('../../../lib/diaspora/user/querying', __FILE__) require File.expand_path('../../../lib/diaspora/user/receiving', __FILE__) require File.expand_path('../../../lib/salmon/salmon', __FILE__) +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 @@ -40,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 @@ -254,6 +265,26 @@ class User end ###Helpers############ + + def accept_invitation!( opts = {} ) + if self.invited? + 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] diff --git a/app/views/invitations/edit.html.haml b/app/views/invitations/edit.html.haml new file mode 100644 index 000000000..e21b0c276 --- /dev/null +++ b/app/views/invitations/edit.html.haml @@ -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" diff --git a/app/views/registrations/new.html.haml b/app/views/registrations/new.html.haml index 25902720e..7e74a2157 100644 --- a/app/views/registrations/new.html.haml +++ b/app/views/registrations/new.html.haml @@ -22,6 +22,5 @@ %p = pr.label :last_name = pr.text_field :last_name - = f.submit t('.sign_up') = render :partial => "devise/shared/links" diff --git a/app/views/users/_profile.haml b/app/views/users/_profile.haml index 9b415a720..a9ea4ad4d 100644 --- a/app/views/users/_profile.haml +++ b/app/views/users/_profile.haml @@ -4,6 +4,7 @@ %h2 Profile += link_to new_user_invitation_path(current_user) = form_for @user do |f| = f.error_messages diff --git a/config/routes.rb b/config/routes.rb index b293c04eb..641c6306f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -12,7 +12,7 @@ Diaspora::Application.routes.draw do devise_for :users, :controllers => {:registrations => "registrations", :password => "devise/passwords", - :invitation => "invitations"} + :invitations => "invitations"} # added public route to user match 'public/:username', :to => 'users#public' match 'users/export', :to => 'users#export' diff --git a/spec/models/user/invite_spec.rb b/spec/models/user/invite_spec.rb new file mode 100644 index 000000000..1bb2bf0f6 --- /dev/null +++ b/spec/models/user/invite_spec.rb @@ -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