module Plugin::World::Keep

Constants

ACCOUNT_CRYPT_KEY_LEN
ACCOUNT_FILE
ACCOUNT_TMP

Public Instance Methods

account_data(name) click to toggle source

アカウント情報を返す

Args

name

アカウントのキー(Symbol)

Return

アカウント情報(Hash)

# File core/plugin/world/keep.rb, line 58
def account_data(name)
  accounts[name.to_sym] or raise ArgumentError, 'account data `#{name}\' does not exists.' end
account_destroy(name) click to toggle source

垢消しの時間だ

Args

name

Return

self

# File core/plugin/world/keep.rb, line 107
def account_destroy(name)
  name = name.to_sym
  @@service_lock.synchronize do
    to_delete = accounts.dup
    to_delete.delete(name)
    @account_data = account_write(to_delete) end
  self end
account_modify(name, options) click to toggle source

アカウント情報を更新する

Args

name

アカウントのキー(Symbol)

options

アカウント情報(Hash)

Exceptions

ArgumentError name のサービスが存在しない場合

Return

self

# File core/plugin/world/keep.rb, line 91
def account_modify(name, options)
  name = name.to_sym
  @@service_lock.synchronize do
    raise ArgumentError, "account `#{name}' does not exists." unless accounts.has_key? name
    @account_data = account_write(
      accounts.merge(
        name => accounts[name].merge(options)))
  end
  self
end
account_register(name, provider:, slug:, **options) click to toggle source

新しいアカウントの情報を登録する

Args

name

アカウントのキー(Symbol)

options

アカウント情報(Hash)

Exceptions

Plugin::World::AlreadyExistError

name のサービスが既に存在している場合

ArgumentError

options の情報が足りない場合

Return

self

# File core/plugin/world/keep.rb, line 70
def account_register(name, provider:, slug:, **options)
  name = name.to_sym
  @@service_lock.synchronize do
    raise Plugin::World::AlreadyExistError, "account #{name} already exists." if accounts.has_key? name
    @account_data = account_write(
      accounts.merge(
        name => options.merge(
          provider: provider,
          slug: slug)))
  end
  self
end
account_write(account_data = @account_data) click to toggle source

アカウント情報をファイルに保存する

# File core/plugin/world/keep.rb, line 116
def account_write(account_data = @account_data)
  FileUtils.mkdir_p File.dirname(ACCOUNT_FILE)
  File.open(ACCOUNT_TMP, 'wb'.freeze) do |file|
    file << encrypt(JSON.dump(account_data)) end
  FileUtils.mv(ACCOUNT_TMP, ACCOUNT_FILE)
  account_data end
accounts() click to toggle source

全てのアカウント情報をオブジェクトとして返す

Return

account_id => {token: ,secret:, …}

# File core/plugin/world/keep.rb, line 28
def accounts
  if @account_data
    @account_data
  else
    @@service_lock.synchronize do
      @account_data ||= if FileTest.exist? ACCOUNT_FILE
        File.open(ACCOUNT_FILE, 'rb'.freeze) do |file|
          decrypted_string = decrypt(file.read)
          begin
            JSON.parse(decrypted_string, symbolize_names: true)
          rescue JSON::ParserError
            # 3.6.4以前はYAMLになっている。
            # 構造自体には互換性があるため単純にJSONにコンバートする
            d = account_write(YAML.load(decrypted_string))
            notice 'Older account data was detected. It was converted newer format.'
            d
          end
        end
      else
        migrate_older_account_data
      end
    end
  end
end
decrypt(binary_data) click to toggle source
# File core/plugin/world/keep.rb, line 129
def decrypt(binary_data)
  cipher = OpenSSL::Cipher.new('bf-ecb').decrypt
  cipher.key = key
  str = cipher.update(binary_data) << cipher.final
  str.force_encoding(Encoding::UTF_8)
  str end
encrypt(str) click to toggle source
# File core/plugin/world/keep.rb, line 123
def encrypt(str)
  cipher = OpenSSL::Cipher.new('bf-ecb').encrypt
  cipher.key_len = ACCOUNT_CRYPT_KEY_LEN
  cipher.key = key
  cipher.update(str) << cipher.final end
key() click to toggle source
# File core/plugin/world/keep.rb, line 21
def key
  key = UserConfig[:account_crypt_key] ||= SecureRandom.random_bytes(ACCOUNT_CRYPT_KEY_LEN)
  key[0, ACCOUNT_CRYPT_KEY_LEN] end