defmodule CIPHER do
require Record
require N2O
use Application
# CIPHER.send 1, "mix.exs"
# CIPHER.down "123412341234"
def start(_, _) do
:logger.add_handlers(:n2o)
app = Supervisor.start_link([], strategy: :one_for_one, name: CIPHER)
login = :application.get_env(:n2o, :login, "")
pass = :application.get_env(:n2o, :pass, "")
:n2o_pi.start(N2O.pi(module: CIPHER, table: :cipher, sup: CIPHER,
state: {"cipherLink", login, pass, 0}, name: "cipherLink"))
app
end
def send(to, doc) do
:gen_server.cast :n2o_pi.pid(:cipher, "cipherLink"), {:send, "cipherLink", to, doc}
end
def down(id) do
:gen_server.cast :n2o_pi.pid(:cipher, "cipherLink"), {:download, id}
end
def proc(:init, pi) do
{:ok, pi}
end
def proc({:send, from, to, doc}, N2O.pi(state: {_, login, pass, cnt}) = pi) do
CIPHER.UP.start(login, pass, from, to, doc, cnt)
{:noreply, pi}
end
def proc({:download, msg_id}, N2O.pi(state: {_, login, pass, _}) = pi) do
CIPHER.DOWN.start(login, pass, msg_id)
{:noreply, pi}
end
# helpers
def error(f, x), do: :logger.error(:io_lib.format('CIPHER ' ++ f, x))
def warning(f, x), do: :logger.warning(:io_lib.format('CIPHER ' ++ f, x))
def debug(f, x), do: :logger.debug(:io_lib.format('CIPHER ' ++ f, x))
def info(f, x), do: :logger.info(:io_lib.format('CIPHER ' ++ f, x))
# REST/JSON API
def cancel(doc), do: spawn(fn -> :n2o_pi.stop(:cipher, doc) end)
def publish(bearer,id,_) do
url = :application.get_env(:n2o, :cipher_upload, []) ++ id
headers = [{'Authorization',bearer}]
{:ok,{status,_headers,body}} = :httpc.request(:put, {url, headers},
[{:timeout,100000}], [{:body_format,:binary}])
CIPHER.debug 'PUBLISH: ~ts ~p', [id,status]
body
end
def metainfo(bearer,id,doc) do
author = [firstName: "Максим",
surname: "Сохацький",
position: "Провідний інженер",
department: "Розробки інформаційних систем",
organization: "ІНФОТЕХ"]
body = :jsone.encode([fileName: doc, description: "Бінарний файл", ownNumber: "123/20",
comment: "Коментар від архіваріуса", authors: [author], outerId: "123/20"])
url = :application.get_env(:n2o, :cipher_upload, []) ++ id ++ '/metadata'
app_json = 'application/json'
headers = [{'Content-Type',app_json},{'Authorization',bearer}]
{:ok,{status,_headers,body}} = :httpc.request(:put, {url, headers, app_json, body},
[{:timeout,100000}], [{:body_format,:binary}])
case status do
{_,200,_} -> CIPHER.debug 'METAINFO: ~ts ~p', [id,status]
_ -> res = :jsone.decode body
msg = :maps.get "message", res
code = :maps.get "code", res
CIPHER.error 'METAINFO: id: ~ts, code: ~ts, message: ~ts', [id,code,msg]
end
body
end
def upload(bearer,doc) do
case :file.read_file(doc) do
{:error, reason} -> {[],reason}
{:ok, file} ->
file_len = :io_lib.format('~p',[:erlang.size(file)])
url = :application.get_env(:n2o, :cipher_upload, []) ++ '1'
octet = 'application/octet-stream'
headers = [{'Authorization',bearer},{'Content-Type',octet},{'Content-Length', file_len}]
{:ok,{status,_headers,body}} = :httpc.request(:post, {url, headers, octet, file},
[{:timeout,100000}], [{:body_format,:binary}])
CIPHER.debug 'UPLOAD: ~p', [status]
res = :jsone.decode body
id = :maps.get("id", res, []) |> :erlang.binary_to_list
{id,res}
end
end
def uploadSignature(bearer,id,doc) do
case :file.read_file(doc <> ".p7s") do
{:error, _reason} -> CIPHER.warning 'P7S is not available for ~p ~p.', [id,doc]
{:ok, file} ->
url = :application.get_env(:n2o, :cipher_upload, []) ++ id ++ '/signature'
octet = 'application/octet-stream'
headers = [{'Authorization',bearer},{'Content-Type',octet}]
{:ok,{status,_headers,body}} = :httpc.request(:put, {url, headers, octet, file},
[{:timeout,100000}], [{:body_format,:binary}])
case status do
{_,200,_} -> CIPHER.debug 'UPLOAD SIGNATURE: ~ts ~p', [id,status]
_ -> res = :jsone.decode body
msg = :maps.get "message", res
code = :maps.get "code", res
CIPHER.error 'UPLOAD SIGNATURE: id: ~ts, code: ~ts, message: ~ts', [id,code,msg]
end
CIPHER.debug 'UPLOAD SIGNATURE: ~p', [status]
{id,body}
end
end
def download(bearer,id) do
url = :application.get_env(:n2o, :cipher_upload, []) ++ id ++ '/data'
headers = [{'Authorization',bearer}]
{:ok,{status,_headers,body}} = :httpc.request(:get, {url, headers},
[{:timeout,100000}], [{:body_format,:binary}])
CIPHER.debug 'DOWNLOAD ~ts: ~p', [id,status]
{status,id,body}
end
def downloadSignature(bearer,id) do
url = :application.get_env(:n2o, :cipher_upload, []) ++ id ++ '/signature'
headers = [{'Authorization',bearer}]
{:ok,{status,_headers,body}} = :httpc.request(:get, {url, headers},
[{:timeout,100000}], [{:body_format,:binary}])
case status do
{_,200,_} -> CIPHER.debug 'DOWNLOAD SIGNATURE: ~ts ~p', [id,status]
_ -> res = :jsone.decode body
msg = :maps.get "message", res
code = :maps.get "code", res
CIPHER.error 'DOWNLOAD SIGNATURE: id: ~ts, code: ~ts, message: ~ts', [id,code,msg]
end
{status,id,:jsone.decode(body)}
end
def auth(login,pass) do
url = :application.get_env(:n2o, :cipher_auth, [])
body = :jsone.encode([grant_type: "password", username: login, client_id: "arch-client", password: pass])
len = :io_lib.format('~p',[:erlang.size(body)])
app_json = 'application/json'
headers = [{'Content-Type',app_json},{'Content-Length', len}]
{:ok,{_status,_headers,body}} = :httpc.request(:post, {url, headers, app_json, body},
[{:timeout,10000}], [{:body_format,:binary}])
res = :jsone.decode body
bearer = :maps.get "token_type", res
CIPHER.debug 'AUTH: ~p', [bearer]
token = :maps.get "access_token", res
bearer <> " " <> token |> :erlang.binary_to_list
end
end