From 3c61365fa1d018e6f58149231286011f66dc6c58 Mon Sep 17 00:00:00 2001 From: ilya Date: Thu, 7 Oct 2010 18:11:17 -0700 Subject: [PATCH 1/8] initial invitable in user --- Gemfile | 2 +- Gemfile.lock | 3 +++ app/models/user.rb | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index df245a480..b0b43e5e0 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ gem 'bundler', '>= 1.0.0' #Security gem 'devise', :git => 'http://github.com/BadMinus/devise.git' - +gem 'devise_invitable', '~> 0.3.4' #Mongo gem 'mongo_mapper', :branch => 'rails3', :git => 'http://github.com/jnunemaker/mongomapper.git' gem 'bson_ext', '1.0.7' diff --git a/Gemfile.lock b/Gemfile.lock index f7f234783..d1d4489ec 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -132,6 +132,8 @@ GEM culerity (0.2.12) daemons (1.1.0) database_cleaner (0.5.2) + devise_invitable (0.3.4) + devise (~> 1.1.0) diff-lcs (1.1.2) em-websocket (0.1.4) addressable (>= 2.1.1) @@ -267,6 +269,7 @@ DEPENDENCIES cucumber-rails (= 0.3.2) database_cleaner devise! + devise_invitable (~> 0.3.4) em-http-request! em-websocket factory_girl_rails diff --git a/app/models/user.rb b/app/models/user.rb index 01094d219..ec712f71f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -15,7 +15,7 @@ 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 From ddb98502b9b46ee6a267eb668cd4e58da797cd0a Mon Sep 17 00:00:00 2001 From: ilya Date: Thu, 7 Oct 2010 19:25:34 -0700 Subject: [PATCH 2/8] setup the controller, still need to make the person --- app/models/user.rb | 2 ++ config/initializers/devise.rb | 5 +++++ config/routes.rb | 3 ++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/models/user.rb b/app/models/user.rb index 31f8d1057..48366d890 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -21,6 +21,8 @@ class User 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 diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 620547cd5..ee032c910 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -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. diff --git a/config/routes.rb b/config/routes.rb index 2d043682d..1a4f6ed3d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -11,7 +11,8 @@ Diaspora::Application.routes.draw do resources :albums devise_for :users, :controllers => {:registrations => "registrations", - :password => "devise/passwords"} + :password => "devise/passwords", + :invitation => "invitations"} # added public route to user match 'public/:username', :to => 'users#public' match 'users/export', :to => 'users#export' From ef3e627bed79447970d039330f2821075bb5cb39 Mon Sep 17 00:00:00 2001 From: ilya Date: Fri, 8 Oct 2010 15:40:42 -0700 Subject: [PATCH 3/8] the users are now made with people --- app/controllers/invitations_controller.rb | 26 +++++++++++++++++ app/models/user.rb | 31 ++++++++++++++++++++ app/views/invitations/edit.html.haml | 25 ++++++++++++++++ app/views/registrations/new.html.haml | 1 - app/views/users/_profile.haml | 1 + config/routes.rb | 2 +- spec/models/user/invite_spec.rb | 35 +++++++++++++++++++++++ 7 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 app/controllers/invitations_controller.rb create mode 100644 app/views/invitations/edit.html.haml create mode 100644 spec/models/user/invite_spec.rb 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 From 8e61b438abeb0b88307e1343a428007bb0f20084 Mon Sep 17 00:00:00 2001 From: ilya Date: Fri, 8 Oct 2010 16:00:58 -0700 Subject: [PATCH 4/8] setting the username --- app/models/user.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/user.rb b/app/models/user.rb index cab054b64..94b18788a 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -268,6 +268,7 @@ class User 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]}" From afad554f0193a4940884ea16e0c3644e401a0a28 Mon Sep 17 00:00:00 2001 From: danielvincent Date: Mon, 11 Oct 2010 13:42:05 -0700 Subject: [PATCH 5/8] DG MS; added link to send invitation, consolidated locale file for devise invitable, upgraded devise to 1.1.3 in the gemfile --- Gemfile | 2 +- Gemfile.lock | 48 +++++++++++---------- app/controllers/invitations_controller.rb | 5 --- app/controllers/users_controller.rb | 4 ++ app/views/aspects/manage.html.haml | 2 +- app/views/invitations/new.html.haml | 10 +++++ app/views/users/mailer/invitation.html.haml | 9 ++++ config/locales/devise.en.yml | 7 +++ config/locales/devise_invitable.en.yml | 8 ---- config/routes.rb | 4 +- 10 files changed, 60 insertions(+), 39 deletions(-) create mode 100644 app/views/invitations/new.html.haml create mode 100644 app/views/users/mailer/invitation.html.haml delete mode 100644 config/locales/devise_invitable.en.yml diff --git a/Gemfile b/Gemfile index 4d85b1531..0e74b4f45 100644 --- a/Gemfile +++ b/Gemfile @@ -4,7 +4,7 @@ gem 'rails', '3.0.0' gem 'bundler', '>= 1.0.0' #Security -gem 'devise', '1.1.2' +gem 'devise', '1.1.3' gem 'devise-mongo_mapper', :git => 'git://github.com/collectiveidea/devise-mongo_mapper' gem 'devise_invitable', '~> 0.3.4' #Mongo diff --git a/Gemfile.lock b/Gemfile.lock index 4b7f686b0..a2a905cc5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -49,21 +49,22 @@ GIT GIT remote: http://github.com/dcu/magent.git - revision: 06513f3dac812469a55f2e365c349af4d2abc92a + revision: 5d664351b305141158fc69fc495456414821adb3 specs: - magent (0.4.2) - mongo (>= 0.1.0) - uuidtools (>= 2.0.0) + magent (1.0.0) + em-websocket + mongo + uuidtools GIT remote: http://github.com/jnunemaker/mongomapper.git - revision: 5a3328244b641fa4f6a3743e9e0b4dd6a1ac2700 + revision: fd59b0ab068be7321f8e84b9dc12fb4fa6b8535d branch: rails3 specs: mongo_mapper (0.8.4) activemodel (~> 3.0.0) activesupport (~> 3.0.0) - plucky (~> 0.3.5) + plucky (~> 0.3.6) GEM remote: http://rubygems.org/ @@ -119,6 +120,8 @@ GEM rack (>= 1.0.0) rack-test (>= 0.5.4) selenium-webdriver (>= 0.0.3) + childprocess (0.0.7) + ffi (~> 0.6.3) columnize (0.3.1) crack (0.1.8) cucumber (0.9.2) @@ -132,7 +135,7 @@ GEM culerity (0.2.12) daemons (1.1.0) database_cleaner (0.5.2) - devise (1.1.2) + devise (1.1.3) bcrypt-ruby (~> 2.1.2) warden (~> 0.10.7) devise_invitable (0.3.4) @@ -173,7 +176,7 @@ GEM subexec (~> 0.0.4) mocha (0.9.8) rake - mongo (1.0.9) + mongo (1.1) bson (>= 1.0.5) net-scp (1.0.4) net-ssh (>= 1.99.1) @@ -183,8 +186,8 @@ GEM net-ssh-gateway (1.0.1) net-ssh (>= 1.99.1) nokogiri (1.4.3.1) - plucky (0.3.5) - mongo (~> 1.0.8) + plucky (0.3.6) + mongo (~> 1.1) polyglot (0.3.1) pubsubhubbub (0.1.1) em-http-request (>= 0.1.5) @@ -210,16 +213,16 @@ GEM rake (0.8.7) rest-client (1.6.1) mime-types (>= 1.16) - rspec (2.0.0.rc) - rspec-core (= 2.0.0.rc) - rspec-expectations (= 2.0.0.rc) - rspec-mocks (= 2.0.0.rc) - rspec-core (2.0.0.rc) - rspec-expectations (2.0.0.rc) + rspec (2.0.0) + rspec-core (= 2.0.0) + rspec-expectations (= 2.0.0) + rspec-mocks (= 2.0.0) + rspec-core (2.0.0) + rspec-expectations (2.0.0) diff-lcs (>= 1.1.2) - rspec-mocks (2.0.0.rc) - rspec-core (= 2.0.0.rc) - rspec-expectations (= 2.0.0.rc) + rspec-mocks (2.0.0) + rspec-core (= 2.0.0) + rspec-expectations (= 2.0.0) rspec-rails (2.0.0.beta.17) rspec (>= 2.0.0.beta.14) webrat (>= 0.7.0) @@ -229,8 +232,9 @@ GEM ruby-debug-base (0.10.3) linecache (>= 0.3) rubyzip (0.9.4) - selenium-webdriver (0.0.28) - ffi (>= 0.6.1) + selenium-webdriver (0.0.29) + childprocess (>= 0.0.7) + ffi (~> 0.6.3) json_pure rubyzip subexec (0.0.4) @@ -269,7 +273,7 @@ DEPENDENCIES carrierwave! cucumber-rails (= 0.3.2) database_cleaner - devise (= 1.1.2) + devise (= 1.1.3) devise-mongo_mapper! devise_invitable (~> 0.3.4) em-http-request! diff --git a/app/controllers/invitations_controller.rb b/app/controllers/invitations_controller.rb index d4f68c197..852904458 100644 --- a/app/controllers/invitations_controller.rb +++ b/app/controllers/invitations_controller.rb @@ -4,15 +4,10 @@ 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 diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 9ef461b20..d78025a47 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -71,6 +71,10 @@ class UsersController < ApplicationController send_data( File.open(tar_path).read, :filename => "#{current_user.id}.tar" ) end + def invite + User.invite!(:email => params[:email]) + end + private def prep_image_url(params) url = APP_CONFIG[:pod_url].chop if APP_CONFIG[:pod_url][-1,1] == '/' diff --git a/app/views/aspects/manage.html.haml b/app/views/aspects/manage.html.haml index 5573fe020..c03b332d3 100644 --- a/app/views/aspects/manage.html.haml +++ b/app/views/aspects/manage.html.haml @@ -27,7 +27,7 @@ - content_for :publish do = link_to(t('.add_a_new_aspect'), "#add_aspect_pane", :id => "add_aspect_button", :class => "new_aspect button", :title => t('.add_a_new_aspect')) - + = link_to "invite a friend!", new_user_invitation_path %ul#aspect_list - for aspect in @aspects %li.aspect diff --git a/app/views/invitations/new.html.haml b/app/views/invitations/new.html.haml new file mode 100644 index 000000000..4b41f06c6 --- /dev/null +++ b/app/views/invitations/new.html.haml @@ -0,0 +1,10 @@ +%h2 Send invitation += form_for resource, :as => resource_name, :url => invitation_path(resource_name) do |f| + = devise_error_messages! + %p + = f.label :email + %br/ + = f.text_field :email + %p= f.submit "Send an invitation" += link_to "Home", after_sign_in_path_for(resource_name) +%br/ diff --git a/app/views/users/mailer/invitation.html.haml b/app/views/users/mailer/invitation.html.haml new file mode 100644 index 000000000..884a8fc27 --- /dev/null +++ b/app/views/users/mailer/invitation.html.haml @@ -0,0 +1,9 @@ +%p + Hello #{@resource.email}! +%p + Someone has invited you to #{root_url}, you can accept it through the link below. +%p= link_to 'Accept invitation', accept_invitation_url(@resource, :invitation_token => @resource.invitation_token) +%p + If you don't want to accept the invitation, please ignore this email. + %br/ + Your account won't be created until you access the link above and set your password. diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml index 5e4e43321..07a2611d0 100644 --- a/config/locales/devise.en.yml +++ b/config/locales/devise.en.yml @@ -30,6 +30,10 @@ en: 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.' + invitations: + send_instructions: 'Your invitation has been sent.' + invitation_token_invalid: 'The invitation token provided is not valid!' + updated: 'Your password was set successfully. You are now signed in.' mailer: confirmation_instructions: subject: 'Confirmation instructions' @@ -37,3 +41,6 @@ en: subject: 'Reset password instructions' unlock_instructions: subject: 'Unlock Instructions' + invitation: + subject: 'A friend wants you to join Diaspora!' + diff --git a/config/locales/devise_invitable.en.yml b/config/locales/devise_invitable.en.yml deleted file mode 100644 index cc1a14842..000000000 --- a/config/locales/devise_invitable.en.yml +++ /dev/null @@ -1,8 +0,0 @@ -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' diff --git a/config/routes.rb b/config/routes.rb index 641c6306f..8fbd132a8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -14,8 +14,8 @@ Diaspora::Application.routes.draw do :password => "devise/passwords", :invitations => "invitations"} # added public route to user - match 'public/:username', :to => 'users#public' - match 'users/export', :to => 'users#export' + match 'public/:username', :to => 'users#public' + match 'users/export', :to => 'users#export' match 'users/export_photos', :to => 'users#export_photos' resources :users, :except => [:create, :new, :show] From be017bfb0a6e0ebfbddf54f59be1ba057d3058c9 Mon Sep 17 00:00:00 2001 From: danielvincent Date: Mon, 11 Oct 2010 14:16:24 -0700 Subject: [PATCH 6/8] DG MS; invite is now a lightbox on feed and manage pages --- app/views/aspects/manage.html.haml | 11 +++++++++-- app/views/invitations/_new.haml | 8 ++++++++ app/views/invitations/new.html.haml | 6 ++---- app/views/shared/_aspect_friends.haml | 6 ++++++ public/javascripts/view.js | 1 + 5 files changed, 26 insertions(+), 6 deletions(-) create mode 100644 app/views/invitations/_new.haml diff --git a/app/views/aspects/manage.html.haml b/app/views/aspects/manage.html.haml index c03b332d3..85296669f 100644 --- a/app/views/aspects/manage.html.haml +++ b/app/views/aspects/manage.html.haml @@ -21,13 +21,20 @@ = request.person.real_name %h3=t('.ignore_remove') - %li.remove + .remove %ul.dropzone %li.grey Drag to ignore/remove + %h3= link_to "Invite a friend!", "#invite_user_pane", :id => "invite_user_button", :class => "invite_user_button", :title => "Invite a friend" + + .yo{ :style => "display:none;"} + #invite_user_pane + = render "invitations/new" + - content_for :publish do = link_to(t('.add_a_new_aspect'), "#add_aspect_pane", :id => "add_aspect_button", :class => "new_aspect button", :title => t('.add_a_new_aspect')) - = link_to "invite a friend!", new_user_invitation_path + + %ul#aspect_list - for aspect in @aspects %li.aspect diff --git a/app/views/invitations/_new.haml b/app/views/invitations/_new.haml new file mode 100644 index 000000000..208e77640 --- /dev/null +++ b/app/views/invitations/_new.haml @@ -0,0 +1,8 @@ +%h2 Send invitation += form_for User.new, :url => invitation_path(User) do |f| + /= devise_error_messages! + %p + = f.label :email + = f.text_field :email + %p= f.submit "Send an invitation" +/= link_to "Home", after_sign_in_path_for(resource_name) diff --git a/app/views/invitations/new.html.haml b/app/views/invitations/new.html.haml index 4b41f06c6..598b16a3d 100644 --- a/app/views/invitations/new.html.haml +++ b/app/views/invitations/new.html.haml @@ -1,10 +1,8 @@ %h2 Send invitation -= form_for resource, :as => resource_name, :url => invitation_path(resource_name) do |f| += form_for User.new, :url => invitation_path(User) do |f| = devise_error_messages! %p = f.label :email - %br/ = f.text_field :email %p= f.submit "Send an invitation" -= link_to "Home", after_sign_in_path_for(resource_name) -%br/ +/= link_to "Home", after_sign_in_path_for(resource_name) diff --git a/app/views/shared/_aspect_friends.haml b/app/views/shared/_aspect_friends.haml index 03da4ee9b..343272dff 100644 --- a/app/views/shared/_aspect_friends.haml +++ b/app/views/shared/_aspect_friends.haml @@ -19,5 +19,11 @@ = render "requests/new_request", :aspect => @aspect -else .clear + %br = link_to t('.add_friends'), aspects_manage_path +%br += link_to "Invite a friend!", "#invite_user_pane", :id => "invite_user_button", :class => "invite_user_button", :title => "Invite a friend" +.yo{ :style => "display:none;"} + #invite_user_pane + = render "invitations/new" diff --git a/public/javascripts/view.js b/public/javascripts/view.js index 4155a593d..eec063bcd 100644 --- a/public/javascripts/view.js +++ b/public/javascripts/view.js @@ -28,6 +28,7 @@ $(document).ready(function(){ //buttons////// $("#add_aspect_button").fancybox({ 'titleShow' : false }); $("#add_request_button").fancybox({ 'titleShow': false }); + $("#invite_user_button").fancybox({ 'titleShow': false }); $(".add_request_button").fancybox({ 'titleShow': false }); $("input[type='submit']").addClass("button"); From 007f6cfb6f0af4d79615fbca0b53de9a446c4c5f Mon Sep 17 00:00:00 2001 From: ilya Date: Mon, 11 Oct 2010 14:58:11 -0700 Subject: [PATCH 7/8] close account --- app/controllers/users_controller.rb | 7 ++++ app/models/person.rb | 1 - app/models/user.rb | 17 ++++++++ app/views/users/_account.haml | 4 ++ config/locales/diaspora/en.yml | 1 + spec/models/user_spec.rb | 62 +++++++++++++++++++++++++++-- 6 files changed, 87 insertions(+), 5 deletions(-) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 9ef461b20..0956c28cc 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -47,6 +47,13 @@ class UsersController < ApplicationController end + def destroy + current_user.destroy + sign_out current_user + flash[:notice] = t('user.destroy') + redirect_to root_path + end + def public user = User.find_by_username(params[:username]) diff --git a/app/models/person.rb b/app/models/person.rb index 62126c9a4..a1dca0089 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -146,6 +146,5 @@ class Person private def remove_all_traces Post.all(:person_id => id).each{|p| p.delete} - Album.all(:person_id => id).each{|p| p.delete} end end diff --git a/app/models/user.rb b/app/models/user.rb index d1ead85cf..270cb7a70 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -39,6 +39,8 @@ class User before_validation :downcase_username, :on => :create + before_destroy :unfriend_everyone, :remove_person + def self.find_for_authentication(conditions={}) if conditions[:username] =~ /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i # email regex conditions[:email] = conditions.delete(:username) @@ -293,5 +295,20 @@ class User def encryption_key OpenSSL::PKey::RSA.new( serialized_private_key ) end + + protected + def remove_person + self.person.destroy + end + + def unfriend_everyone + friends.each{ |friend| + if friend.owner? + friend.owner.unfriended_by (self.person ) + else + self.unfriend( friend ) + end + } + end end diff --git a/app/views/users/_account.haml b/app/views/users/_account.haml index 8bd19d72d..ef416df29 100644 --- a/app/views/users/_account.haml +++ b/app/views/users/_account.haml @@ -27,3 +27,7 @@ = link_to "download my xml", users_export_path, :class => "button" = link_to "download my photos", users_export_photos_path, :class => "button" +%h3 Close Account += link_to "Close Account", current_user, + :confirm => "Are you sure?", :method => :delete, + :class => "button`" diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml index 5a5cc7a43..554f8bcb8 100644 --- a/config/locales/diaspora/en.yml +++ b/config/locales/diaspora/en.yml @@ -114,6 +114,7 @@ en: you_dont_have_any_photos: "You don't have any photos! Go to the" page_to_upload_some: "page to upload some." or: "or" + destroy: "Account successfully closed." comments: comment: ago: "ago" diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 100b9ff39..dfb0f685c 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -6,6 +6,11 @@ require 'spec_helper' describe User do let(:user) { Factory(:user) } + let(:aspect) { user.aspect(:name => 'heroes') } + let(:user2) { Factory(:user) } + let(:aspect2) { user2.aspect(:name => 'stuff') } + let(:user3) { Factory(:user) } + let(:aspect3) { user3.aspect(:name => 'stuff') } describe "validations" do it "downcases the username" do @@ -38,9 +43,6 @@ describe User do end context 'aspects' do - let(:aspect) { user.aspect(:name => 'heroes') } - let(:user2) { Factory(:user) } - let(:aspect2) { user2.aspect(:name => 'stuff') } it 'should delete an empty aspect' do user.drop_aspect(aspect) @@ -48,11 +50,63 @@ describe User do end it 'should not delete an aspect with friends' do - friend_users(user, Aspect.find_by_id(aspect.id), user2, Aspect.find_by_id(aspect2.id)) + friend_users(user, aspect, user2, aspect2) aspect.reload proc{user.drop_aspect(aspect)}.should raise_error /Aspect not empty/ user.aspects.include?(aspect).should == true end end + context 'account removal' do + before do + friend_users(user, aspect, user2, aspect2) + friend_users(user, aspect, user3, aspect3) + end + + it 'should unfriend everyone' do + user.should_receive(:unfriend_everyone) + user.destroy + end + + it 'should remove person' do + user.should_receive(:remove_person) + user.destroy + end + + describe '#remove_person' do + it 'should remove the person object' do + person = user.person + user.destroy + person.reload + person.should be nil + end + + it 'should remove the posts' do + message = user.post(:status_message, :message => "hi", :to => aspect.id) + user.reload + user.destroy + proc{ message.reload }.should raise_error /does not exist/ + end + end + + describe '#unfriend_everyone' do + + before do + user3.delete + end + + it 'should send retractions to remote poeple' do + user.should_receive(:unfriend).once + user.destroy + end + + it 'should unfriend local people' do + user2.friends.count.should be 1 + user.destroy + user2.reload + user2.friends.count.should be 0 + end + end + end + end From d6b08de6fc1e4e0b1dad12c2a28d6e1a18c9dd2b Mon Sep 17 00:00:00 2001 From: ilya Date: Mon, 11 Oct 2010 15:07:17 -0700 Subject: [PATCH 8/8] corrected link on the account page --- app/models/user.rb | 4 ++-- app/views/users/_account.haml | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 8870b43d8..12322dca6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -339,9 +339,9 @@ class User def unfriend_everyone friends.each{ |friend| if friend.owner? - friend.owner.unfriended_by (self.person ) + friend.owner.unfriended_by self.person else - self.unfriend( friend ) + self.unfriend friend end } end diff --git a/app/views/users/_account.haml b/app/views/users/_account.haml index ef416df29..e6b1a7ff1 100644 --- a/app/views/users/_account.haml +++ b/app/views/users/_account.haml @@ -28,6 +28,7 @@ = link_to "download my photos", users_export_photos_path, :class => "button" %h3 Close Account + = link_to "Close Account", current_user, :confirm => "Are you sure?", :method => :delete, - :class => "button`" + :class => "button"