keybase-unofficial-local 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.yardopts +1 -0
- data/LICENSE +21 -0
- data/README.md +15 -0
- data/lib/keybase/local.rb +21 -0
- data/lib/keybase/local/chat.rb +187 -0
- data/lib/keybase/local/config.rb +69 -0
- data/lib/keybase/local/exceptions.rb +29 -0
- data/lib/keybase/local/kbfs.rb +11 -0
- data/lib/keybase/local/team.rb +11 -0
- data/lib/keybase/local/user.rb +34 -0
- metadata +69 -0
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,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: []
|