143 lines
3.7 KiB
Ruby
143 lines
3.7 KiB
Ruby
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
|