keybase-unofficial-local 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 73462754242f448627d5b1b94287a8a81eb39130
4
+ data.tar.gz: 592f7b342ae3c995516c7141004e9e8c472e375b
5
+ SHA512:
6
+ metadata.gz: 00da9053ab49b2fc8b3ae1e8aa2c252ea67bcfee4257faf086068dec72f6a309594d81b5b7cf42681e1fa24f98bb540217fdcda55c3d71be1e62654611f7d121
7
+ data.tar.gz: 0fac2bfe282d57aac3c9a8aa66093f4406c03658853bcaff965a696d4b5b15c10fc14bccdaeefab95c539ebbceea234ea58a672060e2fd0b101524d9a6be4c7b
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --no-private --markup-provider=redcarpet --markup=markdown - *.md LICENSE
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 William Woodruff <william @ yossarian.net>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,15 @@
1
+ keybase-unofficial-local
2
+ ========================
3
+
4
+ An unofficial Ruby library for interacting with a local Keybase installation.
5
+
6
+ ### Installation
7
+
8
+ ```bash
9
+ gem install keybase-unofficial-local
10
+ ```
11
+
12
+ ### Documentation
13
+
14
+ Documentation for the current release can be found on
15
+ [RubyDoc](http://www.rubydoc.info/gems/keybase-unofficial-local/).
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "keybase/core"
4
+
5
+ require_relative "local/exceptions"
6
+ require_relative "local/config"
7
+ require_relative "local/user"
8
+ require_relative "local/kbfs"
9
+ require_relative "local/chat"
10
+ require_relative "local/team"
11
+
12
+ # The primary namespace.
13
+ module Keybase
14
+ # The namespace for `keybase-unofficial-local`.
15
+ module Local
16
+ # The current version of `keybase-unofficial-local`.
17
+ VERSION = "0.0.1"
18
+
19
+ extend Config
20
+ end
21
+ end
@@ -0,0 +1,187 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open3"
4
+ require "json"
5
+ require "ostruct"
6
+
7
+ module Keybase
8
+ module Local
9
+ # Represents Keybase's JSON chat API.
10
+ module Chat
11
+ # The initial arguments to pass when executing Keybase for chatting.
12
+ CHAT_EXEC_ARGS = %w[keybase chat api].freeze
13
+
14
+ class << self
15
+ # @param meth [Symbol] the chat method
16
+ # @param options [Hash] the options hash
17
+ # @return [String] the JSON serialized envelope
18
+ # @api private
19
+ def envelope(meth, options: {})
20
+ {
21
+ method: meth,
22
+ params: {
23
+ options: options,
24
+ },
25
+ }.to_json
26
+ end
27
+
28
+ # @param payload [String] the JSON payload to send to the chat API
29
+ # @return [OpenStruct] a struct mapping of the JSON response
30
+ # @api private
31
+ def chat_call(payload)
32
+ response = Open3.popen3(*CHAT_EXEC_ARGS) do |stdin, stdout, _, _|
33
+ stdin.write payload
34
+ stdin.close # close after writing to let keybase know we're done
35
+ stdout.read
36
+ end
37
+
38
+ JSON.parse response, object_class: OpenStruct
39
+ end
40
+
41
+ # List the user's inbox.
42
+ # @param topic_type [String] the topic type to list by
43
+ # @return [OpenStruct] a struct mapping of the JSON response
44
+ def list_inbox(topic_type: nil)
45
+ payload = envelope :list, options: {
46
+ topic_type: topic_type,
47
+ }
48
+
49
+ chat_call payload
50
+ end
51
+
52
+ # Read a conversation.
53
+ # @param users [Array<String>] a list of the users in the conversation
54
+ # @param peek [Boolean] whether to mark the conversation read
55
+ # @param unread_only [Boolean] whether to fetch unread messages only
56
+ # @return [OpenStruct] a struct mapping of the JSON response
57
+ def conversation(users, peek: false, unread_only: false)
58
+ payload = envelope :read, options: {
59
+ channel: {
60
+ name: Core::U[*users],
61
+ },
62
+ peek: peek,
63
+ unread_only: unread_only,
64
+ }
65
+
66
+ chat_call payload
67
+ end
68
+
69
+ # Send a message to a conversation.
70
+ # @param users [Array<String>] a list of the users in the conversation
71
+ # @param message [String] the message to send
72
+ # @param public [Boolean] whether to send the message to a public channel
73
+ # @return [OpenStruct] a struct mapping of the JSON response
74
+ def send_message(users, message, public: false)
75
+ payload = envelope :send, options: {
76
+ channel: {
77
+ name: Core::U[*users],
78
+ public: public,
79
+ },
80
+ message: {
81
+ body: message,
82
+ },
83
+ }
84
+
85
+ chat_call payload
86
+ end
87
+
88
+ # Delete a message from a conversation.
89
+ # @param users [Array<String>] a list of the users in the conversation
90
+ # @param id [Integer] the id of the message to delete
91
+ # @return [OpenStruct] a struct mapping of the JSON response
92
+ def delete_message(users, id)
93
+ payload = envelope :delete, options: {
94
+ channel: {
95
+ name: Core::U[*users],
96
+ },
97
+ message_id: id,
98
+ }
99
+
100
+ chat_call payload
101
+ end
102
+
103
+ # Edit a message in a conversation.
104
+ # @param users [Array<String>] a list of the users in the conversation
105
+ # @param id [Integer] the id of the message to delete
106
+ # @param message [String] the message to send
107
+ # @return [OpenStruct] a struct mapping of the JSON response
108
+ def edit_message(users, id, message)
109
+ payload = envelope :edit, options: {
110
+ channel: {
111
+ name: Core::U[*users],
112
+ },
113
+ message_id: id,
114
+ message: {
115
+ body: message,
116
+ },
117
+ }
118
+
119
+ chat_call payload
120
+ end
121
+
122
+ # Upload a file to a conversation.
123
+ # @param users [Array<String>] a list of the users in the conversation
124
+ # @param path [String] the pathname of the file to upload
125
+ # @param title [String] the uploaded file's title
126
+ # @return [OpenStruct] a struct mapping of the JSON response
127
+ def upload_attachment(users, path, title)
128
+ payload = envelope :attach, options: {
129
+ channel: {
130
+ name: Core::U[*users],
131
+ },
132
+ filename: path,
133
+ title: title,
134
+ }
135
+
136
+ chat_call payload
137
+ end
138
+
139
+ # Download a file from a conversation.
140
+ # @param users [Array<String>] a list of the users in the conversation
141
+ # @param id [Integer] the id of the message to download from
142
+ # @param path [String] the pathname to download to
143
+ # @return [OpenStruct] a struct mapping of the JSON response
144
+ def download_attachment(users, id, path)
145
+ payload = envelope :download, options: {
146
+ channel: {
147
+ name: Core::U[*users],
148
+ },
149
+ message_id: id,
150
+ output: path,
151
+ }
152
+
153
+ chat_call payload
154
+ end
155
+
156
+ # Make a conversation as read up to a specific ID.
157
+ # @param users [Array<String>] a list of the users in the conversation
158
+ # @param id [Integer] the id of the message to mark up to
159
+ # @return [OpenStruct] a struct mapping of the JSON response
160
+ def mark_conversation(users, id)
161
+ payload = envelope :mark, options: {
162
+ channel: {
163
+ name: Core::U[*users],
164
+ },
165
+ message_id: id,
166
+ }
167
+
168
+ chat_call payload
169
+ end
170
+
171
+ # Mute a conversation.
172
+ # @param users [Array<String>] a list of the users in the conversation
173
+ # @return [OpenStruct] a struct mapping of the JSON response
174
+ def mute_conversation(users)
175
+ payload = envelope :setstatus, options: {
176
+ channel: {
177
+ name: Core::U[*users],
178
+ },
179
+ status: "muted",
180
+ }
181
+
182
+ chat_call payload
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module Keybase
6
+ module Local
7
+ # Methods and constants related to a local Keybase installation.
8
+ module Config
9
+ # The Keybase configuration directory.
10
+ CONFIG_DIR = if Gem.win_platform?
11
+ File.expand_path("#{ENV["LOCALAPPDATA"]}/Keybase").freeze
12
+ else
13
+ File.expand_path("~/.config/keybase").freeze
14
+ end
15
+
16
+ # The Keybase configuration file.
17
+ CONFIG_FILE = File.join(CONFIG_DIR, "config.json").freeze
18
+
19
+ # there's not much this library can do without a local config
20
+ raise Exceptions::KeybaseNotInstalledError unless File.file?(CONFIG_FILE)
21
+
22
+ # The hash from Keybase's configuration file.
23
+ CONFIG_HASH = JSON.parse(File.read(CONFIG_FILE)).freeze
24
+
25
+ # The mountpoint for KBFS.
26
+ KBFS_MOUNT = "/keybase"
27
+
28
+ # @return [String] the currently logged-in user
29
+ def current_user
30
+ CONFIG_HASH["current_user"]
31
+ end
32
+
33
+ # @return [Array<Keybase::Local::User>] a list of all local users known
34
+ # to Keybase
35
+ def local_users
36
+ CONFIG_HASH["users"].map { |_, v| User.new(v) }
37
+ end
38
+
39
+ # @return [String] the user's private KBFS directory
40
+ def private_dir
41
+ File.join(KBFS_MOUNT, "private", current_user)
42
+ end
43
+
44
+ # @return [String] the user's public KBFS directory
45
+ def public_dir
46
+ File.join(KBFS_MOUNT, "public", current_user)
47
+ end
48
+
49
+ # @return [Boolean] whether or not Keybase is currently running
50
+ def running?
51
+ if Gem.win_platform?
52
+ !`tasklist | find "keybase.exe"`.empty?
53
+ else
54
+ # is there a more efficient way to do this that doesn't involve an exec?
55
+ Dir["/proc/[0-9]*/comm"].any? do |comm|
56
+ File.read(comm).chomp == "keybase" rescue false # hooray for TOCTOU
57
+ end
58
+ end
59
+ end
60
+
61
+ # @return [String] the running Keybase's version string
62
+ # @raise [Exceptions::KeybaseNotRunningError] if Keybase is not running
63
+ def running_version
64
+ raise Exceptions::KeybaseNotRunningError unless running?
65
+ `keybase --version`.split[2]
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Keybase
4
+ module Local
5
+ # A namespace for all exceptions defined by {Keybase::Local}.
6
+ module Exceptions
7
+ # Raised if a Keybase installation can't be found.
8
+ class KeybaseNotInstalledError < Core::Exceptions::KeybaseError
9
+ def initialize
10
+ super "keybase needs to be installed"
11
+ end
12
+ end
13
+
14
+ # Raised whenever Keybase is not running locally.
15
+ class KeybaseNotRunningError < Core::Exceptions::KeybaseError
16
+ def initialize
17
+ super "keybase needs to be running"
18
+ end
19
+ end
20
+
21
+ # Raised whenever KBFS is not running locally.
22
+ class KBFSNotRunningError < Core::Exceptions::KeybaseError
23
+ def initialize
24
+ super "KBFS needs to be enabled and running"
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Keybase
4
+ module Local
5
+ # Represents an interface to KBFS.
6
+ # @note This is a stub.
7
+ module KBFS
8
+ # stub
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Keybase
4
+ module Local
5
+ # Represents an interface to Keybase's teams.
6
+ # @note This is a stub.
7
+ module Team
8
+ # stub
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Keybase
4
+ module Local
5
+ # Represents a user known to the local Keybase process.
6
+ # These are (presumably) users that have been logged into locally.
7
+ class User
8
+ # @return [String] the device's unique identifier
9
+ attr_reader :device
10
+
11
+ # @return [String] the user's unique identifier
12
+ attr_reader :id
13
+
14
+ # @return [String] the user's Keybase username
15
+ attr_reader :name
16
+
17
+ # @return [String] some kind of salt
18
+ # @note I have no idea what this field does.
19
+ attr_reader :salt
20
+
21
+ # @param fields [Hash] the user's configuration fields
22
+ # @option fields device [String] the device's unique identifier
23
+ # @option fields id [String] the user's unique identifier
24
+ # @option fields name [String] the user's Keybase username
25
+ # @option fields salt [String] some kind of salt
26
+ def initialize(fields)
27
+ @device = fields["device"]
28
+ @id = fields["id"]
29
+ @name = fields["name"]
30
+ @salt = fields["salt"]
31
+ end
32
+ end
33
+ end
34
+ end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: keybase-unofficial-local
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - William Woodruff
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-09-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: keybase-unofficial-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ description: |
28
+ This library provides access to Keybase's desktop utility from
29
+ Ruby.
30
+ email: william@tuffbizz.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".yardopts"
36
+ - LICENSE
37
+ - README.md
38
+ - lib/keybase/local.rb
39
+ - lib/keybase/local/chat.rb
40
+ - lib/keybase/local/config.rb
41
+ - lib/keybase/local/exceptions.rb
42
+ - lib/keybase/local/kbfs.rb
43
+ - lib/keybase/local/team.rb
44
+ - lib/keybase/local/user.rb
45
+ homepage: https://github.com/woodruffw/keybase-unofficial-local
46
+ licenses:
47
+ - MIT
48
+ metadata: {}
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: 2.3.0
58
+ required_rubygems_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 2.6.13
66
+ signing_key:
67
+ specification_version: 4
68
+ summary: keybase-unofficial-local - Unofficial library for Keybase clients
69
+ test_files: []