Class: Rmega::Nodes::Node
Constant Summary
collapse
- TYPES =
{0 => :file, 1 => :folder, 2 => :root, 3 => :inbox, 4 => :trash}
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
#powm, #rsa_decrypt
#aes_ctr_cipher, #aes_ctr_decrypt, #aes_ctr_encrypt
#aes_ecb_cipher, #aes_ecb_decrypt, #aes_ecb_encrypt
#aes_cbc_cipher, #aes_cbc_decrypt, #aes_cbc_encrypt, #aes_cbc_mac
#children, #empty?, #files, #folders, #parent
Methods included from Loggable
included, #logger
#inspect
Constructor Details
#initialize(session, data) ⇒ Node
Returns a new instance of Node.
18
19
20
21
|
# File 'lib/rmega/nodes/node.rb', line 18
def initialize(session, data)
@session = session
@data = data
end
|
Instance Attribute Details
#data ⇒ Object
Returns the value of attribute data.
9
10
11
|
# File 'lib/rmega/nodes/node.rb', line 9
def data
@data
end
|
#session ⇒ Object
Returns the value of attribute session.
9
10
11
|
# File 'lib/rmega/nodes/node.rb', line 9
def session
@session
end
|
Class Method Details
.each_chunk(size, &block) ⇒ Object
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
# File 'lib/rmega/nodes/node.rb', line 110
def self.each_chunk(size, &block)
start, p = 0, 0
return if size <= 0
loop do
offset = p < 8 ? (131072 * (p += 1)) : 1048576
next_start = offset + start
if next_start >= size
yield(start, size - start)
break
else
yield(start, offset)
start = next_start
end
end
end
|
Instance Method Details
#attributes ⇒ Object
146
147
148
149
150
151
152
153
154
155
156
157
|
# File 'lib/rmega/nodes/node.rb', line 146
def attributes
encrypted = data['a'] || data['at']
return if !encrypted or encrypted.empty?
node_key = NodeKey.load(decrypted_file_key)
encrypted = Utils.base64urldecode(encrypted)
encrypted.strip! if encrypted.size % 16 != 0
json = aes_cbc_decrypt(node_key.aes_key, encrypted)
json.strip!
json.gsub!(/^MEGA\{(.+)\}.*/, '{\1}')
return JSON.parse(json)
end
|
#decrypted_file_key ⇒ Object
133
134
135
136
137
138
139
140
141
142
143
144
|
# File 'lib/rmega/nodes/node.rb', line 133
def decrypted_file_key
h, shared_key = *process_shared_key
if shared_key
aes_ecb_decrypt(shared_key, file_keys[h])
elsif file_key
aes_ecb_decrypt(master_key, file_key)
else
ary = Rmega::Nodes::Factory.public_handle_and_key_from_url(public_url)
Utils.base64urldecode(ary[1])
end
end
|
#each_chunk(&block) ⇒ Object
129
130
131
|
# File 'lib/rmega/nodes/node.rb', line 129
def each_chunk(&block)
self.class.each_chunk(filesize, &block)
end
|
#file_key ⇒ Object
78
79
80
81
|
# File 'lib/rmega/nodes/node.rb', line 78
def file_key
k = file_keys.values.first
return k ? k : nil
end
|
#file_keys ⇒ Object
67
68
69
70
71
72
73
74
75
76
|
# File 'lib/rmega/nodes/node.rb', line 67
def file_keys
return {} unless data['k']
pairs = data['k'].split('/')
pairs.inject({}) do |hash, pair|
h, k = pair.split(':')
hash[h] = Utils.base64urldecode(k)
hash
end
end
|
#handle ⇒ Object
55
56
57
|
# File 'lib/rmega/nodes/node.rb', line 55
def handle
data['h']
end
|
#name ⇒ Object
63
64
65
|
# File 'lib/rmega/nodes/node.rb', line 63
def name
attributes['n'] if attributes
end
|
#parent_handle ⇒ Object
59
60
61
|
# File 'lib/rmega/nodes/node.rb', line 59
def parent_handle
data['p']
end
|
#process_shared_key ⇒ Object
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
# File 'lib/rmega/nodes/node.rb', line 87
def process_shared_key
h = (shared_keys.keys & file_keys.keys).first
return [h, shared_keys[h]] if h
sk = data['sk']
return unless sk
shared_key = if sk.size > 22
sk = Utils.base64_mpi_to_bn(sk)
sk = rsa_decrypt(sk, rsa_privk)
sk = sk.to_s(16)
sk = '0' + sk if sk.size % 2 > 0
Utils.hexstr_to_bstr(sk)[0..15]
else
aes_ecb_decrypt(master_key, Utils.base64urldecode(sk))
end
shared_keys[handle] = shared_key
[handle, shared_key]
end
|
#public_handle ⇒ Object
27
28
29
|
# File 'lib/rmega/nodes/node.rb', line 27
def public_handle
@public_handle ||= request(a: 'l', n: handle)
end
|
#public_url ⇒ Object
23
24
25
|
# File 'lib/rmega/nodes/node.rb', line 23
def public_url
@public_url ||= "https://mega.nz/file/#{public_handle}\##{Utils.base64urlencode(decrypted_file_key)}"
end
|
#rename(new_name) ⇒ Object
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
# File 'lib/rmega/nodes/node.rb', line 38
def rename(new_name)
node_key = NodeKey.load(decrypted_file_key)
_attr = serialize_attributes(attributes.merge("n" => Utils.utf8(new_name)))
_attr = aes_cbc_encrypt(node_key.aes_key, _attr)
_attr = Utils.base64urlencode(_attr)
resp = request(:a => "a", :attr => _attr, :key => Utils.base64urlencode(node_key.aes_key), :n => handle)
if resp != 0
raise("Rename failed")
else
@data['a'] = _attr
return self
end
end
|
#serialize_attributes(hash) ⇒ Object
31
32
33
34
35
36
|
# File 'lib/rmega/nodes/node.rb', line 31
def serialize_attributes(hash)
str = "MEGA"
str << hash.to_json
str << ("\x00" * (16 - (str.bytesize % 16)))
return str
end
|
#shared_root? ⇒ Boolean
83
84
85
|
# File 'lib/rmega/nodes/node.rb', line 83
def shared_root?
data['su'] && data['sk'] && data['k']
end
|
#type ⇒ Object
159
160
161
|
# File 'lib/rmega/nodes/node.rb', line 159
def type
TYPES[data['t']]
end
|