Class: KBSecret::Session

Inherits:
Object
  • Object
show all
Defined in:
lib/kbsecret/session.rb

Overview

Represents a session of Keybase users with collective read and/or write access to a collection of records.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(label: :default) ⇒ Session

Note:

This does not create a new session, but loads one already specified in Config::CONFIG_FILE. To create a new session, see Config#configure_session.

Returns a new instance of Session.

Parameters:

  • label (String, Symbol) (defaults to: :default)

    the label of the session to initialize

Raises:



31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/kbsecret/session.rb', line 31

def initialize(label: :default)
  @label     = label.to_sym
  @config    = Config.session(@label)

  # team sessions don't have explicit users
  unless @config[:team]
    raise Exceptions::SessionLoadError, "no users in session" if @config[:users].empty?
  end

  @path    = rel_path mkdir: true
  @records = load_records!
end

Instance Attribute Details

#configHash (readonly)

Returns the session-specific configuration, from Config::CONFIG_FILE.

Returns:



14
15
16
# File 'lib/kbsecret/session.rb', line 14

def config
  @config
end

#labelSymbol (readonly)

Returns the session's label.

Returns:

  • (Symbol)

    the session's label



10
11
12
# File 'lib/kbsecret/session.rb', line 10

def label
  @label
end

#pathString (readonly)

Returns the fully-qualified path of the session.

Returns:

  • (String)

    the fully-qualified path of the session



17
18
19
# File 'lib/kbsecret/session.rb', line 17

def path
  @path
end

Class Method Details

.[](label) ⇒ Session

Parameters:

  • label (String, Symbol)

    the label of the session to initialize

Returns:

See Also:



22
23
24
# File 'lib/kbsecret/session.rb', line 22

def self.[](label)
  new(label: label)
end

Instance Method Details

#==(other) ⇒ Boolean

Note:

The equality of two sessions is determined solely by them having the same session directory, not by having the same label or the same in-memory state.

Compare two sessions for equality.

Parameters:

  • other (Session)

    the other object to compare against

Returns:

  • (Boolean)

    whether or not the two sessions are equal



162
163
164
# File 'lib/kbsecret/session.rb', line 162

def ==(other)
  other.class == self.class && other.path == path
end

#[](label) ⇒ Record::Abstract?

Returns the record with the requested label, if extant.

Parameters:

  • label (String, Symbol)

    the label of the record to fetch

Returns:



46
47
48
# File 'lib/kbsecret/session.rb', line 46

def [](label)
  @records.find { |r| r.label == label.to_s }
end

#add_record(type, label, *args, overwrite: false) ⇒ void

This method returns an undefined value.

Add a record to the session.

Examples:

session.add_record :login, "gmail", "[email protected]", "hunter2"

Parameters:

  • type (String, Symbol)

    the type of record (see Record.record_types)

  • label (String, Symbol)

    the new record's label

  • args (Array<String>)

    the record-type specific arguments

  • overwrite (Boolean) (defaults to: false)

    whether or not to overwrite an existing record if necessary

Raises:



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/kbsecret/session.rb', line 82

def add_record(type, label, *args, overwrite: false)
  klass = Record.class_for(type.to_sym)
  arity = klass.external_fields.length

  raise Exceptions::RecordCreationArityError.new(arity, args.size) unless arity == args.size

  if record? label
    raise Exceptions::RecordOverwriteError.new(self, label) unless overwrite
    delete_record label
  end

  body   = klass.external_fields.zip(args).to_h
  record = klass.new(self, label.to_s, **body)

  records << record
  record.sync!
end

#delete_record(label) ⇒ void

This method returns an undefined value.

Delete a record from the session, if it exists. Does nothing if no such record can be found.

Examples:

session.delete_record "gmail"

Parameters:

  • label (String, Symbol)

    the label of the record to delete



128
129
130
131
132
133
134
# File 'lib/kbsecret/session.rb', line 128

def delete_record(label)
  record = records.find { |r| r.label == label.to_s }
  return unless record

  File.delete(record.path)
  records.delete(record)
end

#import_record(record, overwrite: false) ⇒ void

This method returns an undefined value.

Import an existing record from another session.

Examples:

session.import_record other_session["gmail"], overwrite: true

Parameters:

  • record (Record::Abstract)

    the record to import

  • overwrite (Boolean) (defaults to: false)

    whether or not to overwrite an existing record if necessary

Raises:



108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/kbsecret/session.rb', line 108

def import_record(record, overwrite: false)
  raise Exceptions::SessionImportError, self if self == record.session

  if record? record.label
    raise Exceptions::RecordOverwriteError.new(self, record.label) unless overwrite
    delete_record record.label
  end

  klass = record.class
  imported_record = klass.load!(self, record.to_h)
  records << imported_record
  imported_record.sync!
end

#load_records!Array<Record::Abstract>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Load all records associated with the session.

Returns:



169
170
171
172
173
# File 'lib/kbsecret/session.rb', line 169

def load_records!
  record_paths.map do |path|
    Record.load_record! self, path
  end
end

#record?(label) ⇒ Boolean

Returns whether or not the session contains a record with the given label.

Parameters:

  • label (String, Symbol)

    the label to test for

Returns:

  • (Boolean)

    whether or not the session contains a record with the given label



139
140
141
# File 'lib/kbsecret/session.rb', line 139

def record?(label)
  record_labels.include?(label.to_s)
end

#record_labelsArray<String>

Returns the labels of all records known to the session.

Examples:

session.record_labels # => ["website1", "apikey1", "website2"]

Returns:

  • (Array<String>)

    the labels of all records known to the session



64
65
66
# File 'lib/kbsecret/session.rb', line 64

def record_labels
  records.map(&:label)
end

#record_pathsArray<String>

Returns the fully qualified paths of all records in the session.

Returns:

  • (Array<String>)

    the fully qualified paths of all records in the session



153
154
155
# File 'lib/kbsecret/session.rb', line 153

def record_paths
  Dir[File.join(path, "*.json")]
end

#records(type = nil) ⇒ Array<Record::Abstract>

All records (of a given type) in the session.

Parameters:

  • type (String, Symbol) (defaults to: nil)

    the type of the records to return (or nil for all)

Returns:



53
54
55
56
57
58
59
# File 'lib/kbsecret/session.rb', line 53

def records(type = nil)
  if type
    @records.select { |r| r.type == type.to_sym }
  else
    @records
  end
end

#rel_path(mkdir: false) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the fully qualified path to the session.

Parameters:

  • mkdir (Boolean) (defaults to: false)

    whether or not to make the session path

Returns:

  • (String)

    the fully qualified path to the session



178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/kbsecret/session.rb', line 178

def rel_path(mkdir: false)
  path = if @config[:team]
           File.join(Keybase::Local::Config::KBFS_MOUNT, "team", @config[:team], "kbsecret",
                     @config[:root])
         else
           # /keybase/private/[u1,u2,...,uN]/kbsecret/[session]
           File.join(Keybase::Local::Config::KBFS_MOUNT, "private",
                     Keybase::Core::U[@config[:users]], "kbsecret", @config[:root])
         end

  FileUtils.mkdir_p path if mkdir

  path
end

#unlink!void

Note:

Use this with caution, as all files under the session path will be deleted. Furthermore, the session path itself will be deleted, and this object will become garbage.

This method returns an undefined value.

Delete the entire session.



148
149
150
# File 'lib/kbsecret/session.rb', line 148

def unlink!
  FileUtils.rm_rf(path)
end