app/models/user.rb
# check/update sha256 signatures. Used in cross server client communication
# 1) update sha256 for user
# 2) mark sha256 as updated for online friends (must download new sha256 signatures - short friends list from ping response)
# 3) mark sha256 as updated for online friends of friends (must download new sha256 signatures - short friends list from ping response)
# params:
# - force=false. normal update. skip update operation if unchanged sha256 signature
# - force=true.  true. set sha256_updated_at and friend_sha256_updated_at for user, friends and friend of friends.
#                update marked users will be included in next ping :friends response
check/update sha256 signatures. Used in cross server client communication
1) update sha256 for user
2) mark sha256 as updated for online friends (must download new sha256 signatures - short friends list from ping response)
3) mark sha256 as updated for online friends of friends (must download new sha256 signatures - short friends list from ping response)
params:
force=false. normal update. skip update operation if unchanged sha256 signature
force=true.  true. set sha256_updated_at and friend_sha256_updated_at for user, friends and friend of friends.
update marked users will be included in next ping :friends response
check / update sha256 signatures . Used in cross server client communication 1 ) update sha256 for user 2 ) mark sha256 as updated for online friends ( must download new sha256 signatures - short friends list from ping response ) 3 ) mark sha256 as updated for online friends of friends ( must download new sha256 signatures - short friends list from ping response ) params : force = false . normal update . skip update operation if unchanged sha256 signature force = true . true . set sha256_updated_at and friend_sha256_updated_at for user friends and friend of friends . update marked users will be included in next ping : friends response
def update_sha256 (force)
    old_sha256 = self.sha256
    new_sha256 = self.calc_sha256(SystemParameter.secret)
    return if !force and (old_sha256 == new_sha256)
    loop do
      if !User.where('sha256 = ? and id <> ?', new_sha256, self.id).first
        self.old_sha256 = old_sha256
        self.sha256 = new_sha256
        self.sha256_updated_at = Time.zone.now
        self.save!
        online_user_ids = []
        Ping.where(:server_id => nil).each { |p| online_user_ids += p.user_ids }
        online_user_ids.uniq!
        User.where(:user_id =>
                       Friend.select(:user_id_receiver).
                           where(:user_id_giver => self.user_id). 
                       where(:user_id_receiver => online_user_ids). 
                       where(:user_id_receiver => ServerUser.select(:user_id).where('verified_at is not null'))). 
        update_all(:friend_sha256_updated_at => Time.zone.now)
        User.where(:user_id =>
                       Friend.select(:user_id_receiver).
                           where(:user_id_giver => Friend.select(:user_id_receiver).where(:user_id_giver => self.user_id)). 
                       where(:user_id_receiver => online_user_ids). 
                       where(:user_id_receiver => ServerUser.select(:user_id).where('verified_at is not null'))). 
        update_all(:friend_sha256_updated_at => Time.zone.now)
        break
      end
      SystemParameter.new_secret
      new_sha256 = self.calc_sha256(SystemParameter.secret)
    end 
    if old_sha256 != new_sha256
      server_users = verified_server_users.includes(:server, :user).order(:server_id)
      Server.save_sha256_changed_message(2, server_users)
    end
    if self.remote_sha256_update_info
      logger.debug2 "check pending user info update operation - this server is updating user info after detecting changed sha256 signature in incoming message"
      logger.debug2 "user #{self.debug_info}"
      logger.debug2 "remote_sha256_update_info = #{self.remote_sha256_update_info}"
      old_sha256 = self.remote_sha256_update_info[:remote_sha256]
      old_secret = self.remote_sha256_update_info[:system_secret]
      new_sha256 = calc_sha256(old_secret)
      sha256_ok = (new_sha256 == old_sha256)
      logger.debug2 "old_secret = #{old_secret}, old_sha256 = #{old_sha256}, new_sha256 = #{new_sha256}, sha256_ok = #{sha256_ok}"
      if sha256_ok
        logger.debug2 "Ok. sha256 signature ok after user info update. pending verify gifts operation can continue"
      elsif old_sha256 == new_sha256
        logger.error2 "Error. Unchanged user info and still invalid remote sha256 signature"
      else
        logger.error2 "Error. Changed user info and invalid remote sha256 signature"
      end
      self.remote_sha256_updated_at = nil
      self.remote_sha256_update_info = nil
      self.save!
    end
  end
def update_sha256 ( force ) old_sha256 = self . sha256 new_sha256 = self . calc_sha256 ( SystemParameter . secret ) return if ! force and ( old_sha256 == new_sha256 ) loop do if ! User . where ( 'sha256 = ? and id <> ?' , new_sha256 , self . id ) . first self . old_sha256 = old_sha256 self . sha256 = new_sha256 self . sha256_updated_at = Time . zone . now self . save! online_user_ids = [ ] Ping . where ( :server_id => nil ) . each { | p | online_user_ids += p . user_ids } online_user_ids . uniq! User . where ( :user_id => Friend . select ( :user_id_receiver ) . where ( :user_id_giver => self . user_id ) . where ( :user_id_receiver => online_user_ids ) . where ( :user_id_receiver => ServerUser . select ( :user_id ) . where ( 'verified_at is not null' ) ) ) . update_all ( :friend_sha256_updated_at => Time . zone . now ) User . where ( :user_id => Friend . select ( :user_id_receiver ) . where ( :user_id_giver => Friend . select ( :user_id_receiver ) . where ( :user_id_giver => self . user_id ) ) . where ( :user_id_receiver => online_user_ids ) . where ( :user_id_receiver => ServerUser . select ( :user_id ) . where ( 'verified_at is not null' ) ) ) . update_all ( :friend_sha256_updated_at => Time . zone . now ) break end SystemParameter . new_secret new_sha256 = self . calc_sha256 ( SystemParameter . secret ) end if old_sha256 != new_sha256 server_users = verified_server_users . includes ( :server , :user ) . order ( :server_id ) Server . save_sha256_changed_message ( 2 , server_users ) end if self . remote_sha256_update_info logger . debug2 "check pending user info update operation - this server is updating user info after detecting changed sha256 signature in incoming message" logger . debug2 "user #{self.debug_info}" logger . debug2 "remote_sha256_update_info = #{self.remote_sha256_update_info}" old_sha256 = self . remote_sha256_update_info [ :remote_sha256 ] old_secret = self . remote_sha256_update_info [ :system_secret ] new_sha256 = calc_sha256 ( old_secret ) sha256_ok = ( new_sha256 == old_sha256 ) logger . debug2 "old_secret = #{old_secret}, old_sha256 = #{old_sha256}, new_sha256 = #{new_sha256}, sha256_ok = #{sha256_ok}" if sha256_ok logger . debug2 "Ok. sha256 signature ok after user info update. pending verify gifts operation can continue" elsif old_sha256 == new_sha256 logger . error2 "Error. Unchanged user info and still invalid remote sha256 signature" else logger . error2 "Error. Changed user info and invalid remote sha256 signature" end self . remote_sha256_updated_at = nil self . remote_sha256_update_info = nil self . save! end end
check/update sha256 signatures.
check / update sha256 signatures .
# loop - system secret may have to change to keep sha256 signatures unique # new unique sha256 # 1) update sha256 for user # 2) update sha256 timestamp for users that is a) friend of user. b) online user and c) verified user # just updated user # online users # remote users # 3) update sha256 timestamp for users that is a) friend of friend. b) online user and c) verified user # friend of just updated user # online users # remote users # doublet sha256 signature. sha256 signatures must be unique. generate new system secret # loop # send user sha256 signature changed message to other Gofreerev servers # other server must check sha256 signature and sha256_updated_at timestamp and optional ask a client to download new user info from login provider # check pending user info update operation - this server is updating user info after detecting changed sha256 signature in incoming message
force
<not_specific>