refactor wip

This commit is contained in:
danielgrippi 2011-08-15 23:05:14 -07:00 committed by Maxwell Salzberg
parent bf0eb3dac3
commit 159fce3ef2
2 changed files with 149 additions and 57 deletions

View file

@ -10,21 +10,98 @@ class Invitation < ActiveRecord::Base
validates_presence_of :sender,
:recipient,
:aspect
:aspect,
:identifier,
:service
attr_accessible :sender, :recipient, :aspect, :service, :identifier
before_validation :attach_recipent, :on => :create
before_create :ensure_not_inviting_self
validate :valid_identifier?
validates_uniqueness_of :sender, :scope => :recipient
def identifier=(ident)
ident.downcase! if ident
ident
end
def not_inviting_yourself
if self.identifier == self.sender.email
errors[:base] << 'You can not invite yourself'
end
end
def attach_recipient
self.recipient = User.find_or_create_by_invitation(self)
end
def skip_invitation?
end
def valid_identifier?
if self.service == 'email'
unless self.identifier.match(Devise.email_regexp)
errors[:base] << 'You can not invite yourself'
end
end
end
end
# @param opts [Hash] Takes :identifier, :service, :idenfitier, :from, :message
# @return [User]
def self.invite(opts={})
opts[:identifier].downcase! if opts[:identifier]
# return if the current user is trying to invite himself via email
return false if opts[:identifier] == opts[:from].email
if existing_user = self.find_existing_user(opts[:service], opts[:identifier])
# If the sender of the invitation is already connected to the person
# he is inviting, raise an error.
if opts[:from].contact_for(opts[:from].person)
raise "You are already connceted to this person"
# Check whether or not the existing User has already been invited;
# and if so, start sharing with the Person.
elsif not existing_user.invited?
@ -48,18 +125,6 @@ class Invitation < ActiveRecord::Base
# @param service [String] String representation of the service invitation provider (i.e. facebook, email)
# @param identifier [String] String representation of the reciepients identity on the provider (i.e. 'bob.smith', bob@aol.com)
# @return [User]
def self.find_existing_user(service, identifier)
unless existing_user = User.where(:invitation_service => service,
:invitation_identifier => identifier).first
if service == 'email'
existing_user ||= User.where(:email => identifier).first
else
existing_user ||= User.joins(:services).where(:services => {:type => "Services::#{service.titleize}", :uid => identifier}).first
end
end
existing_user
end
# @params opts [Hash] Takes :from, :existing_user, :service, :identifier, :message
# @return [User]
@ -71,25 +136,9 @@ class Invitation < ActiveRecord::Base
invitee.valid?
# Return a User immediately if an invalid email is passed in
return invitee if opts[:service] == 'email' && !opts[:identifier].match(Devise.email_regexp)
if invitee.new_record?
invitee.errors.clear
invitee.serialized_private_key = User.generate_key if invitee.serialized_private_key.blank?
invitee.send(:generate_invitation_token)
elsif invitee.invitation_token.nil?
return invitee
end
# Logic if there is an explicit sender
if opts[:from]
invitee.save(:validate => false)
Invitation.create!(:sender => opts[:from],
:recipient => invitee,
:aspect => opts[:into],
:message => opts[:message])
invitee.reload
end
invitee.skip_invitation = (opts[:service] != 'email')
invitee.invite!

View file

@ -59,24 +59,40 @@ class User < ActiveRecord::Base
:invitation_service,
:invitation_identifier
# Sometimes we access the person in a strange way and need to do this
# @note we should make this method depricated.
#
# @return [Person]
def save_person!
self.person.save if self.person && self.person.changed?
self.person
def self.find_or_create_by_invitation(invitation)
service = invitation.service
identifier = invitation.identifier
unless existing_user = User.joins(:invitations)
.where(:invitation_service => service,
:invitation_identifier => identifier).first
if service == 'email'
existing_user = User.where(:email => identifier).first
else
existing_user = User.joins(:services).where(:services => {:type => "Services::#{service.titleize}", :uid => identifier}).first
end
end
if existing_user
return existing_user
else
end
end
# Set the User's email to the one they've been invited at, if the user
# is being created via an invitation.
#
# @return [User]
def infer_email_from_invitation_provider
self.email = self.invitation_identifier if self.invitation_service == 'email'
self
def self.create_from_invitation!
user = User.new
user.generate_keys
user.generate_invitation_token
# we need to make a custom validator here to make this safer
user.save(:validate => false)
user
end
def update_user_preferences(pref_hash)
if self.disable_mail
UserPreference::VALID_EMAIL_TYPES.each{|x| self.user_preferences.find_or_create_by_email_type(x)}
@ -291,6 +307,8 @@ class User < ActiveRecord::Base
end
end
###Invitations############
def invite_user(aspect_id, service, identifier, invite_message = "")
if aspect = aspects.find(aspect_id)
@ -355,13 +373,12 @@ class User < ActiveRecord::Base
opts[:person][:profile] = Profile.new(opts[:person][:profile])
end
#TODO make this User#person=
self.person = Person.new(opts[:person])
self.person.diaspora_handle = "#{opts[:username]}@#{AppConfig[:pod_uri].authority}"
self.person.url = AppConfig[:pod_url]
self.serialized_private_key = User.generate_key if self.serialized_private_key.blank?
self.person.serialized_public_key = OpenSSL::PKey::RSA.new(self.serialized_private_key).public_key
self.generate_keys
self
end
@ -379,10 +396,6 @@ class User < ActiveRecord::Base
aq
end
def self.generate_key
key_size = (Rails.env == 'test' ? 512 : 4096)
OpenSSL::PKey::RSA::generate(key_size)
end
def encryption_key
OpenSSL::PKey::RSA.new(serialized_private_key)
@ -433,4 +446,34 @@ class User < ActiveRecord::Base
i += 1
end
end
# Generate public/private keys for User and associated Person
def generate_keys
key_size = (Rails.env == 'test' ? 512 : 4096)
self.serialized_private_key = OpenSSL::PKey::RSA::generate(key_size) if self.serialized_private_key.blank?
if self.person && self.person.serialized_public_key.blank?
self.person.serialized_public_key = OpenSSL::PKey::RSA.new(self.serialized_private_key).public_key
end
end
# Sometimes we access the person in a strange way and need to do this
# @note we should make this method depricated.
#
# @return [Person]
def save_person!
self.person.save if self.person && self.person.changed?
self.person
end
# Set the User's email to the one they've been invited at, if the user
# is being created via an invitation.
#
# @return [User]
def infer_email_from_invitation_provider
self.email = self.invitation_identifier if self.invitation_service == 'email'
self
end
end