Merge branch 'master' of github.com:diaspora/diaspora into import

Conflicts:
	app/controllers/users_controller.rb
This commit is contained in:
maxwell 2010-10-13 23:09:48 -07:00
commit e218ab6780
18 changed files with 236 additions and 105 deletions

24
.gitignore vendored
View file

@ -1,4 +1,17 @@
# Configuration files
config/app_config.yml
config/fb_config.yml
config/initializers/secret_token.rb
.bundle
# Uploded files and local files
log/*
public/uploads/*
public/source.tar
tmp/**/*
db/*.sqlite3
# Temporary files of every sort
.DS_Store
.idea
.rvmrc
@ -8,17 +21,6 @@
*.swp
*~
bin/*
config/app_config.yml
config/fb_config.yml
config/initializers/secret_token.rb
db/*.sqlite3
log/*
nbproject
gpg/diaspora-development/*.gpg
gpg/diaspora-production/*.gpg
gpg/*/random_seed
patches-*
public/uploads/*
public/source.tar
tmp/**/*
capybara-*.html

View file

@ -9,6 +9,7 @@ class ApplicationController < ActionController::Base
before_filter :set_friends_and_status, :except => [:create, :update]
before_filter :count_requests
before_filter :fb_user_info
before_filter :set_invites
layout :layout_by_resource
@ -37,6 +38,12 @@ class ApplicationController < ActionController::Base
@request_count = Request.for_user(current_user).size if current_user
end
def set_invites
if current_user
@invites = current_user.invites
end
end
def fb_user_info
if current_user
@access_token = warden.session[:access_token]

View file

@ -3,6 +3,22 @@
# the COPYRIGHT file.
class InvitationsController < Devise::InvitationsController
def create
begin
self.resource = current_user.invite_user(params[resource_name])
flash[:notice] = I18n.t 'invitations.create.sent'
rescue RuntimeError => e
if e.message == "You have no invites"
flash[:error] = I18n.t 'invitations.create.no_more'
elsif e.message == "You already invited this person"
flash[:error] = I18n.t 'invitations.create.already_sent'
else
raise e
end
end
redirect_to after_sign_in_path_for(resource_name)
end
def update
begin
user = User.find_by_invitation_token(params["user"]["invitation_token"])

View file

@ -104,7 +104,6 @@ class UsersController < ApplicationController
end
private
def prep_image_url(params)
url = APP_CONFIG[:pod_url].chop if APP_CONFIG[:pod_url][-1,1] == '/'

View file

@ -2,9 +2,7 @@
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
require File.join(Rails.root, 'lib/diaspora/user/friending')
require File.join(Rails.root, 'lib/diaspora/user/querying')
require File.join(Rails.root, 'lib/diaspora/user/receiving')
require File.join(Rails.root, 'lib/diaspora/user')
require File.join(Rails.root, 'lib/salmon/salmon')
class InvitedUserValidator < ActiveModel::Validator
@ -20,9 +18,7 @@ end
class User
include MongoMapper::Document
plugin MongoMapper::Devise
include Diaspora::UserModules::Friending
include Diaspora::UserModules::Querying
include Diaspora::UserModules::Receiving
include Diaspora::UserModules
include Encryptor::Private
QUEUE = MessageHandler.new
@ -31,8 +27,10 @@ class User
key :username, :unique => true
key :serialized_private_key, String
key :invites, Integer, :default => 5
key :invitation_token, String
key :invitation_sent_at, DateTime
key :inviter_ids, Array
key :friend_ids, Array
key :pending_request_ids, Array
key :visible_post_ids, Array
@ -40,6 +38,7 @@ class User
one :person, :class_name => 'Person', :foreign_key => :owner_id
many :inviters, :in => :inviter_ids, :class_name => 'User'
many :friends, :in => :friend_ids, :class_name => 'Person'
many :visible_people, :in => :visible_person_ids, :class_name => 'Person' # One of these needs to go
many :pending_requests, :in => :pending_request_ids, :class_name => 'Request'
@ -266,7 +265,37 @@ class User
end
end
###Helpers############
###Invitations############
def invite_user( opts = {} )
if self.invites > 0
invited_user = User.invite!(:email => opts[:email], :inviter => self)
self.invites = self.invites - 1
self.save!
invited_user
else
raise "You have no invites"
end
end
def self.invite!(attributes={})
inviter = attributes.delete(:inviter)
invitable = find_or_initialize_with_error_by(:email, attributes.delete(:email))
invitable.attributes = attributes
if invitable.inviters.include?(inviter)
raise "You already invited this person"
else
invitable.inviters << inviter
end
if invitable.new_record?
invitable.errors.clear if invitable.email.try(:match, Devise.email_regexp)
else
invitable.errors.add(:email, :taken) unless invitable.invited?
end
invitable.invite! if invitable.errors.empty?
invitable
end
def accept_invitation!( opts = {} )
if self.invited?
@ -283,11 +312,13 @@ class User
person_hash = opts.delete(:person)
self.person = Person.create(person_hash)
self.person.save
self.invitation_token = nil
self.save
self
end
end
###Helpers############
def self.instantiate!( opts = {} )
opts[:person][:diaspora_handle] = "#{opts[:username]}@#{APP_CONFIG[:terse_pod_url]}"
opts[:person][:url] = APP_CONFIG[:pod_url]

View file

@ -26,6 +26,7 @@
%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"
%h3= "You have #{@invites} invites."
.yo{ :style => "display:none;"}
#invite_user_pane

View file

@ -1,9 +1,9 @@
%p
Hello #{@resource.email}!
%p
Someone has invited you to #{root_url}, you can accept it through the link below.
#{(@resource.inviters.count == 1)? ( @resource.inviters.first.real_name + " has") : (@resource.inviters.map{|inv| inv.real_name}.join(",") + " have")} 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.
Your account won't be created until you access the link above and sign up.

View file

@ -24,6 +24,8 @@
%br
= link_to "Invite a friend!", "#invite_user_pane", :id => "invite_user_button", :class => "invite_user_button", :title => "Invite a friend"
%br
= "You have #{@invites} invites."
.yo{ :style => "display:none;"}
#invite_user_pane
= render "invitations/new"

View file

@ -1,46 +0,0 @@
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.'
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'
reset_password_instructions:
subject: 'Reset password instructions'
unlock_instructions:
subject: 'Unlock Instructions'
invitation:
subject: 'A friend wants you to join Diaspora!'

View file

@ -1,7 +1,3 @@
# Copyright (c) 2010, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
en:
errors:
messages:
@ -11,30 +7,40 @@ en:
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."
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."
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."
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."
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."
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."
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: "Confirmation instructions"
reset_password_instructions: "Reset password instructions"
unlock_instructions: "Unlock Instructions"
confirmation_instructions:
subject: 'Confirmation instructions'
reset_password_instructions:
subject: 'Reset password instructions'
unlock_instructions:
subject: 'Unlock Instructions'
invitation:
subject: 'A friend wants you to join Diaspora!'

View file

@ -154,6 +154,14 @@ en:
sign_up: "Sign up"
create:
success: "You've joined Diaspora!"
invitations:
create:
sent: 'Your invitation has been sent.'
no_more: 'You have no more invitations.'
already_sent: 'You already invited this person.'
invitation_token_invalid: 'The invitation token provided is not valid!'
updated: 'Your password was set successfully. You are now signed in.'
status_messages:
new_status_message:
tell_me_something_good: "tell me something good"

11
lib/diaspora/user.rb Normal file
View file

@ -0,0 +1,11 @@
require File.join(Rails.root, 'lib/diaspora/user/friending')
require File.join(Rails.root, 'lib/diaspora/user/querying')
require File.join(Rails.root, 'lib/diaspora/user/receiving')
module Diaspora
module UserModules
include Friending
include Querying
include Receiving
end
end

View file

@ -1,5 +1,9 @@
## Diaspora RPM tools
NOTE: This does not work ATM, see discussions on Gemfile.lock in
attached to a commit 12/10 (yea, I know, you calll it 10/12, but you
are wrong ;)
Creates diaspora source tarballs and RPM packages
An alternative to the capistrano system, providing classic, binary RPM

View file

@ -1,5 +1,10 @@
## Package-oriented install for ubuntu.
NOTE: This does not work ATM, see discussions on Gemfile.lock in
attached to a commit 12/10 (yea, I know, you calll it 10/12, but you
are wrong ;)
Here are somediaspora-installdiaspora-install scripts to install diaspora on Ubuntu. They are designed to
work as a first step towards packaging, but should be usable as is.

View file

@ -3,13 +3,23 @@
# Start diaspora websocket and main services
#
# Is someone listening on 3000 already? (ipv4 only test ?)
services=$( netstat -nl | grep '[^:]:3000[ \t]')
test -n "$services" && {
echo "Warning: something is already using port 3000"
echo " $services"
}
# Is someone listening on the port already? (ipv4 only test ?)
PORT=3000
while getopts ":p:" OPTION
do
if [ $OPTION == 'p' ]
then
PORT=$OPTARG
fi
done
services=$( netstat -nl | grep ":$PORT[ \t]")
test -n "$services" && {
echo "Warning: something is already using port "$PORT
echo " $services"
exit
}
# Check if Mongo is running

View file

@ -21,7 +21,7 @@ describe User do
end
context 'malicious friend attack vector' do
it 'ovewrites messages with a different user' do
it 'overwrites messages with a different user' do
original_message = user2.post :status_message, :message => 'store this!', :to => aspect2.id
user.receive_salmon(user2.salmon(original_message).xml_for(user.person))
@ -34,7 +34,7 @@ describe User do
user.raw_visible_posts.first.message.should == "store this!"
end
it 'ovewrites messages which apear to be from the same user' do
it 'overwrites messages which apear to be from the same user' do
original_message = user2.post :status_message, :message => 'store this!', :to => aspect2.id
user.receive_salmon(user2.salmon(original_message).xml_for(user.person))
user.raw_visible_posts.count.should be 1
@ -47,7 +47,7 @@ describe User do
user.raw_visible_posts.first.message.should == "store this!"
end
it 'overites another persons profile' do
it 'should not overwrite another persons profile profile' do
profile = user2.profile.clone
profile.first_name = "Not BOB"
@ -58,5 +58,28 @@ describe User do
user2.profile.first_name.should == "Robert"
end
it 'should not overwrite another persons profile through comment' do
pending
user_status = user.post(:status_message, :message => "hi", :to => 'all')
comment = Comment.new(:person_id => user3.person.id, :text => "hey", :post => user_status)
comment.creator_signature = comment.sign_with_key(user3.encryption_key)
comment.post_creator_signature = comment.sign_with_key(user.encryption_key)
person = user3.person
original_url = person.url
original_id = person.id
puts original_url
comment.person.url = "http://bad.com/"
user3.delete
person.delete
comment.to_diaspora_xml.include?("bad.com").should be true
user2.receive_salmon(user.salmon(comment).xml_for(user2.person))
comment.person.url.should == original_url
Person.first(:id => original_id).url.should == original_url
end
end
end

View file

@ -5,18 +5,55 @@
require 'spec_helper'
describe User do
let!(:invited_user) { create_user_with_invitation("abc")}
let(:inviter) {Factory.create :user}
let(:inviter_with_3_invites) {Factory.create :user, :invites => 3}
let!(:invited_user) { create_user_with_invitation("abc", :email => "email@example.com", :inviter => inviter)}
let(:invited_user1) { create_user_with_invitation("abc", :email => "email@example.com", :inviter => inviter_with_3_invites)}
let(:invited_user2) { create_user_with_invitation("abc", :email => "email@example.com", :inviter => inviter_with_3_invites)}
let(:invited_user3) { create_user_with_invitation("abc", :email => "email@example.com", :inviter => inviter_with_3_invites)}
context "creating invites" do
it 'should invite the user' do
pending "weird wrong number of arguments error (0 for 2), which changes if you put in two args"
#User.should_receive(:invite!).and_return(invited_user)
inviter.invite_user(:email => "email@example.com")
end
it 'should add the inviter to the invited_user' do
User.should_receive(:invite!).and_return(invited_user)
invited_user = inviter.invite_user(:email => "email@example.com")
invited_user.reload
invited_user.inviters.include?(inviter).should be true
end
end
context "limit on invites" do
it 'does not invite users after 3 invites' do
User.stub!(:invite!).and_return(invited_user1,invited_user2,invited_user3)
inviter_with_3_invites.invite_user(:email => "email1@example.com")
inviter_with_3_invites.invite_user(:email => "email2@example.com")
inviter_with_3_invites.invite_user(:email => "email3@example.com")
proc{inviter_with_3_invites.invite_user(:email => "email4@example.com")}.should raise_error /You have no invites/
end
it 'does not invite people I already invited' do
pending "this is really weird to test without the actual method working"
User.stub!(:invite!).and_return(invited_user1,invited_user1)
inviter_with_3_invites.invite_user(:email => "email1@example.com")
proc{inviter_with_3_invites.invite_user(:email => "email1@example.com")}.should raise_error /You already invited that person/
end
end
context "the acceptance of an invitation" do
it "should create the person with the passed in params" do
Person.count.should be 0
person_count = Person.count
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
Person.count.should be person_count + 1
u.person.profile.first_name.should == "Bob"
end
end
@ -25,11 +62,12 @@ describe User do
end
def create_user_with_invitation(invitation_token, attributes={})
inviter = attributes.delete(:inviter)
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.inviters << inviter
user.save(:validate => false)
user
end

View file

@ -22,6 +22,20 @@ describe User do
user.valid?
user.username.should == "someuppercase"
end
it "confirms the password" do
pending "I cannot figure out why this doesn't work. --Raphael"
user = User.instantiate!(
:email => "tom@tom.joindiaspora.com",
:username => "tom",
:password => "evankorth",
:password_confirmation => "potatoes",
:person => Person.new(
:profile => Profile.new( :first_name => "Alexander", :last_name => "Hamiltom" ))
)
user.created_at.should be_nil
user.valid?.should be_false
end
end
describe '#diaspora_handle' do