class Person include MongoMapper::Document include ROXML include Encryptor::Public xml_accessor :_id xml_accessor :email xml_accessor :url xml_accessor :profile, :as => Profile xml_reader :exported_key key :url, String key :email, String, :unique => true key :serialized_key, String key :owner_id, ObjectId key :user_refs, Integer, :default => 0 one :profile, :class_name => 'Profile' many :albums, :class_name => 'Album', :foreign_key => :person_id belongs_to :owner, :class_name => 'User' timestamps! before_destroy :remove_all_traces before_validation :clean_url validates_presence_of :email, :url, :profile, :serialized_key validates_format_of :url, :with => /^(https?):\/\/[a-z0-9]+([\-\.]{1}[a-z0-9]+)*(\.[a-z]{2,5})?(:[0-9]{1,5})?(\/.*)?$/ix def self.search(query) Person.all('$where' => "function() { return this.email.match(/^#{query}/i) || this.profile.first_name.match(/^#{query}/i) || this.profile.last_name.match(/^#{query}/i); }") end def real_name "#{profile.first_name.to_s} #{profile.last_name.to_s}" end def owns?(post) self.id == post.person.id end def receive_url "#{self.url}receive/users/#{self.id}/" end def encryption_key OpenSSL::PKey::RSA.new( serialized_key ) end def encryption_key= new_key raise TypeError unless new_key.class == OpenSSL::PKey::RSA serialized_key = new_key.export end def public_key_hash Base64.encode64 OpenSSL::Digest::SHA256.new(self.exported_key).to_s end def public_key encryption_key.public_key end def exported_key encryption_key.public_key.export end def exported_key= new_key raise "Don't change a key" if serialized_key @serialized_key = new_key end def self.by_webfinger( identifier ) local_person = Person.first(:email => identifier.gsub('acct:', '')) if local_person local_person elsif !identifier.include?("localhost") begin f = Redfinger.finger(identifier) rescue SocketError => e raise "Diaspora server for #{identifier} not found" if e.message =~ /Name or service not known/ end #raise "No diaspora user found at #{identifier}" Person.from_webfinger_profile(identifier, f ) end end def self.from_webfinger_profile( identifier, profile) new_person = Person.new public_key = profile.links.select{|x| x.rel == 'diaspora-public-key'}.first.href new_person.exported_key = Base64.decode64 public_key new_person.email = identifier puts profile.hcard.first[:href] hcard = Prism.find profile.hcard.first[:href], :hcard pp hcard.class debugger receive_url = profile.links.select{ |l| l.rel == 'http://joindiaspora.com/seed_location'}.first.href new_person.url = receive_url.split('receive').first new_person.profile = Profile.new(:first_name => "Anon", :last_name => "ymous") if new_person.save new_person else nil end end def remote? owner.nil? end def as_json(opts={}) { :person => { :id => self.id, :name => self.real_name, :email => self.email, :url => self.url, :exported_key => exported_key } } end protected def clean_url self.url ||= "http://localhost:3000/" if self.class == User if self.url self.url = 'http://' + self.url unless self.url.match('http://' || 'https://') self.url = self.url + '/' if self.url[-1,1] != '/' end end 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