private DataNode ValidateRequest(string[] args) { if (args.Length >= 3) { string dapp = args[args.Length - 2]; string token = args[args.Length - 1]; if (authTokens.ContainsKey(dapp)) { if (authTokens[dapp] == token) { return(null); } } } return(APIUtils.FromAPIResult(new Error() { message = "Invalid or missing API token" })); }
public void Execute(string cmd, Action <int, DataNode, bool> callback) { var args = cmd.Split(','); DataNode root; int id = 0; if (int.TryParse(args[0], out id)) { } if (args.Length != 2) { root = APIUtils.FromAPIResult(new Error() { message = "Malformed request" }); callback(id, root, false); return; } cmd = args[1]; args = cmd.Split('/'); bool success = false; var requestType = args[0]; if (requestType != "authorize") { var status = this.Status; if (status != WalletStatus.Ready) { root = APIUtils.FromAPIResult(new Error() { message = $"Wallet is {status}" }); callback(id, root, false); return; } } if (_isPendingRequest) { root = APIUtils.FromAPIResult(new Error() { message = $"A previouus request is still pending" }); callback(id, root, false); return; } _isPendingRequest = true; switch (requestType) { case "authorize": { if (args.Length == 2) { string token; var dapp = args[1]; if (authTokens.ContainsKey(dapp)) { token = authTokens[dapp]; success = true; root = APIUtils.FromAPIResult(new Authorization() { wallet = this.Name, dapp = dapp, token = token }); } else { this.Authorize(dapp, (authorized, error) => { if (authorized) { var bytes = new byte[32]; rnd.NextBytes(bytes); token = Base16.Encode(bytes); authTokens[dapp] = token; success = true; root = APIUtils.FromAPIResult(new Authorization() { wallet = this.Name, dapp = dapp, token = token }); } else { root = APIUtils.FromAPIResult(new Error() { message = error }); } callback(id, root, success); _isPendingRequest = false; }); return; } } else { root = APIUtils.FromAPIResult(new Error() { message = $"authorize: Invalid amount of arguments: {args.Length} instead of 2" }); } break; } case "getAccount": { root = ValidateRequest(args); if (root == null) { var account = this.GetAccount(); root = APIUtils.FromAPIResult(account); success = true; } break; } case "signTx": { root = ValidateRequest(args); if (root == null) { if (args.Length == 7) { var nexus = args[1]; var chain = args[2]; var script = Base16.Decode(args[3]); byte[] payload = args[4].Length > 0 ? Base16.Decode(args[4]) : null; SignTransaction(nexus, chain, script, payload, id, (hash, txError) => { if (hash != Hash.Null) { success = true; root = APIUtils.FromAPIResult(new Transaction() { hash = hash.ToString() }); } else { root = APIUtils.FromAPIResult(new Error() { message = txError }); } callback(id, root, success); _isPendingRequest = false; }); return; } else { root = APIUtils.FromAPIResult(new Error() { message = $"signTx: Invalid amount of arguments: {args.Length} instead of 7" }); } } break; } case "invokeScript": { root = ValidateRequest(args); if (root == null) { if (args.Length == 4) { var script = Base16.Decode(args[1]); InvokeScript(script, id, (invokeResult, invokeError) => { if (invokeResult != null) { success = true; root = APIUtils.FromAPIResult(new Invocation() { result = Base16.Encode(invokeResult) }); } else { root = APIUtils.FromAPIResult(new Error() { message = invokeError }); } callback(id, root, success); _isPendingRequest = false; }); return; } else { root = APIUtils.FromAPIResult(new Error() { message = $"invokeScript: Invalid amount of arguments: {args.Length} instead of 4" }); } } break; } default: root = APIUtils.FromAPIResult(new Error() { message = "Invalid request type" }); break; } callback(id, root, success); _isPendingRequest = false; }
public void Execute(string cmd, Action <int, DataNode, bool> callback) { var args = cmd.Split(','); DataNode root; int id = 0; if (int.TryParse(args[0], out id)) { } if (args.Length != 2) { root = APIUtils.FromAPIResult(new Error() { message = "Malformed request" }); callback(id, root, false); return; } cmd = args[1]; args = cmd.Split('/'); bool success = false; var requestType = args[0]; if (requestType != "authorize") { var status = this.Status; if (status != WalletStatus.Ready) { root = APIUtils.FromAPIResult(new Error() { message = $"Wallet is {status}" }); callback(id, root, false); return; } } switch (requestType) { case "authorize": { if (args.Length == 2) { string token; var dapp = args[1]; if (authTokens.ContainsKey(dapp)) { token = authTokens[dapp]; } else { var bytes = new byte[32]; rnd.NextBytes(bytes); token = Base16.Encode(bytes); authTokens[dapp] = token; } success = true; root = APIUtils.FromAPIResult(new Authorization() { wallet = this.Name, dapp = dapp, token = token }); } else { root = APIUtils.FromAPIResult(new Error() { message = "Invalid amount of arguments" }); } break; } case "getAccount": { root = ValidateRequest(args); if (root == null) { var account = this.GetAccount(); root = APIUtils.FromAPIResult(account); success = true; } break; } case "signTx": { root = ValidateRequest(args); if (root == null) { if (args.Length == 3) { var script = args[1]; SignTransaction(script, id, callback); return; } else { root = APIUtils.FromAPIResult(new Error() { message = "Invalid amount of arguments" }); } } break; } case "invokeScript": { root = ValidateRequest(args); if (root == null) { if (args.Length == 3) { var script = args[1]; InvokeScript(script, id, callback); return; } else { root = APIUtils.FromAPIResult(new Error() { message = "Invalid amount of arguments" }); } } break; } default: root = APIUtils.FromAPIResult(new Error() { message = "Invalid request type" }); break; } callback(id, root, success); }
public void Execute(string cmd, Action <int, DataNode, bool> callback) { var args = cmd.Split(','); DataNode answer; int id = 0; if (!int.TryParse(args[0], out id)) { answer = APIUtils.FromAPIResult(new Error() { message = "Invalid request id" }); callback(id, answer, false); return; } if (args.Length != 2) { answer = APIUtils.FromAPIResult(new Error() { message = "Malformed request" }); callback(id, answer, false); return; } cmd = args[1]; args = cmd.Split('/'); bool success = false; var requestType = args[0]; if (requestType != "authorize") { var status = this.Status; if (status != WalletStatus.Ready) { answer = APIUtils.FromAPIResult(new Error() { message = $"Wallet is {status}" }); callback(id, answer, false); return; } } if (_isPendingRequest) { answer = APIUtils.FromAPIResult(new Error() { message = $"A previous request is still pending" }); callback(id, answer, false); return; } _isPendingRequest = true; switch (requestType) { case "version": { answer = APIUtils.FromAPIResult(new Invocation() { result = LinkProtocol.ToString() }); success = true; break; } case "authorize": { if (args.Length == 2) { string token; var dapp = args[1]; if (authTokens.ContainsKey(dapp)) { token = authTokens[dapp]; success = true; answer = APIUtils.FromAPIResult(new Authorization() { wallet = this.Name, nexus = this.Nexus, dapp = dapp, token = token }); } else { var bytes = new byte[32]; rnd.NextBytes(bytes); token = Base16.Encode(bytes); this.Authorize(dapp, token, (authorized, error) => { if (authorized) { authTokens[dapp] = token; success = true; answer = APIUtils.FromAPIResult(new Authorization() { wallet = this.Name, nexus = this.Nexus, dapp = dapp, token = token }); } else { answer = APIUtils.FromAPIResult(new Error() { message = error }); } callback(id, answer, success); _isPendingRequest = false; }); return; } } else { answer = APIUtils.FromAPIResult(new Error() { message = $"authorize: Invalid amount of arguments: {args.Length} instead of 2" }); } break; } case "getAccount": { answer = ValidateRequest(args); if (answer == null) { var account = this.GetAccount(); answer = APIUtils.FromAPIResult(account); success = true; } break; } case "signData": { answer = ValidateRequest(args); if (answer == null) { if (args.Length == 5) { var data = Base16.Decode(args[1], false); if (data == null) { answer = APIUtils.FromAPIResult(new Error() { message = $"signTx: Invalid input received" }); } else { var signatureKind = (SignatureKind)Enum.Parse(typeof(SignatureKind), args[2], true); SignData(data, signatureKind, id, (signature, random, txError) => { if (signature != null) { success = true; answer = APIUtils.FromAPIResult(new Signature() { signature = signature, random = random }); } else { answer = APIUtils.FromAPIResult(new Error() { message = txError }); } callback(id, answer, success); _isPendingRequest = false; }); } return; } else { answer = APIUtils.FromAPIResult(new Error() { message = $"signTx: Invalid amount of arguments: {args.Length} instead of 5" }); } } break; } case "signTx": { answer = ValidateRequest(args); if (answer == null) { if (args.Length == 7) { var nexus = args[1]; if (nexus == this.Nexus) { args = args.Skip(1).ToArray(); } else { answer = APIUtils.FromAPIResult(new Error() { message = $"signTx: Invalid nexus: '{nexus}' expected '{this.Nexus}' instead" }); break; } } if (args.Length == 6) { var chain = args[1]; var script = Base16.Decode(args[2], false); if (script == null) { answer = APIUtils.FromAPIResult(new Error() { message = $"signTx: Invalid script data" }); } else { byte[] payload = args[4].Length > 0 ? Base16.Decode(args[4], false) : null; SignTransaction(chain, script, payload, id, (hash, txError) => { if (hash != Hash.Null) { success = true; answer = APIUtils.FromAPIResult(new Transaction() { hash = hash.ToString() }); } else { answer = APIUtils.FromAPIResult(new Error() { message = txError }); } callback(id, answer, success); _isPendingRequest = false; }); } return; } else { answer = APIUtils.FromAPIResult(new Error() { message = $"signTx: Invalid amount of arguments: {args.Length} instead of 7" }); } } break; } case "invokeScript": { answer = ValidateRequest(args); if (answer == null) { if (args.Length == 4) { var script = Base16.Decode(args[1], false); if (script == null) { answer = APIUtils.FromAPIResult(new Error() { message = $"signTx: Invalid script data" }); } else { InvokeScript(script, id, (invokeResult, invokeError) => { if (invokeResult != null) { success = true; answer = APIUtils.FromAPIResult(new Invocation() { result = Base16.Encode(invokeResult) }); } else { answer = APIUtils.FromAPIResult(new Error() { message = invokeError }); } callback(id, answer, success); _isPendingRequest = false; }); return; } } else { answer = APIUtils.FromAPIResult(new Error() { message = $"invokeScript: Invalid amount of arguments: {args.Length} instead of 4" }); } } break; } case "writeArchive": { answer = ValidateRequest(args); if (answer == null) { if (args.Length == 6) { var archiveHash = Hash.Parse(args[1]); var blockIndex = int.Parse(args[2]); var bytes = Base16.Decode(args[3], false); if (bytes == null) { answer = APIUtils.FromAPIResult(new Error() { message = $"invokeScript: Invalid archive data" }); } else { WriteArchive(archiveHash, blockIndex, bytes, (result, error) => { if (result) { success = true; answer = APIUtils.FromAPIResult(new Transaction() { hash = archiveHash.ToString() }); } else { answer = APIUtils.FromAPIResult(new Error() { message = error }); } callback(id, answer, success); _isPendingRequest = false; }); } return; } else { answer = APIUtils.FromAPIResult(new Error() { message = $"invokeScript: Invalid amount of arguments: {args.Length} instead of 6" }); } } break; } default: answer = APIUtils.FromAPIResult(new Error() { message = "Invalid request type" }); break; } callback(id, answer, success); _isPendingRequest = false; }
public void Execute(string cmd, Action <int, DataNode, bool> callback) { var args = cmd.Split(','); DataNode answer; int id = 0; if (!int.TryParse(args[0], out id)) { answer = APIUtils.FromAPIResult(new Error() { message = "Invalid request id" }); callback(id, answer, false); return; } if (args.Length != 2) { answer = APIUtils.FromAPIResult(new Error() { message = "Malformed request" }); callback(id, answer, false); return; } cmd = args[1]; args = cmd.Split('/'); bool success = false; var requestType = args[0]; if (requestType != "authorize") { var status = this.Status; if (status != WalletStatus.Ready) { answer = APIUtils.FromAPIResult(new Error() { message = $"Wallet is {status}" }); callback(id, answer, false); return; } } if (_isPendingRequest) { answer = APIUtils.FromAPIResult(new Error() { message = $"A previous request is still pending" }); callback(id, answer, false); return; } _isPendingRequest = true; Connection connection = null; if (requestType != "authorize") { connection = ValidateRequest(args); if (connection == null) { answer = APIUtils.FromAPIResult(new Error() { message = "Invalid or missing API token" }); callback(id, answer, false); return; } // exclude dapp/token args args = args.Take(args.Length - 2).ToArray(); } args = args.Skip(1).ToArray(); switch (requestType) { case "authorize": { if (args.Length == 1 || args.Length == 2) { string token; var dapp = args[0]; int version; if (args.Length == 2) { var str = args[1]; if (!int.TryParse(str, out version)) { answer = APIUtils.FromAPIResult(new Error() { message = $"authorize: Invalid version: {str}" }); callback(id, answer, false); _isPendingRequest = false; return; } } else { version = 1; } if (_connections.ContainsKey(dapp)) { connection = _connections[dapp]; success = true; answer = APIUtils.FromAPIResult(new Authorization() { wallet = this.Name, nexus = this.Nexus, dapp = dapp, token = connection.Token, version = connection.Version }); } else { var bytes = new byte[32]; rnd.NextBytes(bytes); token = Base16.Encode(bytes); this.Authorize(dapp, token, version, (authorized, error) => { if (authorized) { _connections[dapp] = new Connection(token, version); success = true; answer = APIUtils.FromAPIResult(new Authorization() { wallet = this.Name, nexus = this.Nexus, dapp = dapp, token = token }); } else { answer = APIUtils.FromAPIResult(new Error() { message = error }); } callback(id, answer, success); _isPendingRequest = false; }); return; } } else { answer = APIUtils.FromAPIResult(new Error() { message = $"authorize: Invalid amount of arguments: {args.Length}" }); } break; } case "getAccount": { int expectedLength; switch (connection.Version) { case 1: expectedLength = 0; break; default: expectedLength = 1; break; } if (args.Length == expectedLength) { string platform; if (connection.Version >= 2) { platform = args[0].ToLower(); } else { platform = "phantasma"; } GetAccount(platform, (account, error) => { if (error == null) { success = true; answer = APIUtils.FromAPIResult(account); } else { answer = APIUtils.FromAPIResult(new Error() { message = error }); } callback(id, answer, success); _isPendingRequest = false; }); return; } else { answer = APIUtils.FromAPIResult(new Error() { message = $"getAccount: Invalid amount of arguments: {args.Length}" }); } break; } case "signData": { int expectedLength; switch (connection.Version) { case 1: expectedLength = 2; break; default: expectedLength = 3; break; } if (args.Length == expectedLength) { var data = Base16.Decode(args[0], false); if (data == null) { answer = APIUtils.FromAPIResult(new Error() { message = $"signTx: Invalid input received" }); } else { SignatureKind signatureKind; if (!Enum.TryParse <SignatureKind>(args[1], out signatureKind)) { answer = APIUtils.FromAPIResult(new Error() { message = $"signData: Invalid signature: " + args[1] }); callback(id, answer, false); _isPendingRequest = false; return; } var platform = connection.Version >= 2 ? args[2].ToLower() : "phantasma"; SignData(platform, signatureKind, data, id, (signature, random, txError) => { if (signature != null) { success = true; answer = APIUtils.FromAPIResult(new Signature() { signature = signature, random = random }); } else { answer = APIUtils.FromAPIResult(new Error() { message = txError }); } callback(id, answer, success); _isPendingRequest = false; }); } return; } else { answer = APIUtils.FromAPIResult(new Error() { message = $"signTx: Invalid amount of arguments: {args.Length}" }); } break; } case "signTx": { int expectedLength; switch (connection.Version) { case 1: expectedLength = 4; break; default: expectedLength = 5; break; } if (args.Length == expectedLength) { int index = 0; if (connection.Version == 1) { var txNexus = args[index]; index++; if (txNexus != this.Nexus) { answer = APIUtils.FromAPIResult(new Error() { message = $"signTx: Expected nexus {this.Nexus}, instead got {txNexus}" }); callback(id, answer, false); _isPendingRequest = false; return; } } var chain = args[index]; index++; var script = Base16.Decode(args[index], false); index++; if (script == null) { answer = APIUtils.FromAPIResult(new Error() { message = $"signTx: Invalid script data" }); } else { byte[] payload = args[index].Length > 0 ? Base16.Decode(args[index], false) : null; index++; string platform; SignatureKind signatureKind; if (connection.Version >= 2) { if (!Enum.TryParse <SignatureKind>(args[index], out signatureKind)) { answer = APIUtils.FromAPIResult(new Error() { message = $"signTx: Invalid signature: " + args[index] }); callback(id, answer, false); _isPendingRequest = false; return; } index++; platform = args[index].ToLower(); index++; } else { platform = "phantasma"; signatureKind = SignatureKind.Ed25519; } SignTransaction(platform, signatureKind, chain, script, payload, id, (hash, txError) => { if (hash != Hash.Null) { success = true; answer = APIUtils.FromAPIResult(new Transaction() { hash = hash.ToString() }); } else { answer = APIUtils.FromAPIResult(new Error() { message = txError }); } callback(id, answer, success); _isPendingRequest = false; }); } return; } else { answer = APIUtils.FromAPIResult(new Error() { message = $"signTx: Invalid amount of arguments: {args.Length}" }); } break; } case "invokeScript": { if (args.Length == 2) { var chain = args[0]; var script = Base16.Decode(args[1], false); if (script == null) { answer = APIUtils.FromAPIResult(new Error() { message = $"signTx: Invalid script data" }); } else { InvokeScript(chain, script, id, (invokeResult, invokeError) => { if (invokeResult != null) { success = true; answer = APIUtils.FromAPIResult(new Invocation() { result = Base16.Encode(invokeResult) }); } else { answer = APIUtils.FromAPIResult(new Error() { message = invokeError }); } callback(id, answer, success); _isPendingRequest = false; }); return; } } else { answer = APIUtils.FromAPIResult(new Error() { message = $"invokeScript: Invalid amount of arguments: {args.Length}" }); } break; } case "writeArchive": { if (args.Length == 3) { var archiveHash = Hash.Parse(args[0]); var blockIndex = int.Parse(args[1]); var bytes = Base16.Decode(args[2], false); if (bytes == null) { answer = APIUtils.FromAPIResult(new Error() { message = $"invokeScript: Invalid archive data" }); } else { WriteArchive(archiveHash, blockIndex, bytes, (result, error) => { if (result) { success = true; answer = APIUtils.FromAPIResult(new Transaction() { hash = archiveHash.ToString() }); } else { answer = APIUtils.FromAPIResult(new Error() { message = error }); } callback(id, answer, success); _isPendingRequest = false; }); } return; } else { answer = APIUtils.FromAPIResult(new Error() { message = $"writeArchive: Invalid amount of arguments: {args.Length}" }); } break; } default: answer = APIUtils.FromAPIResult(new Error() { message = "Invalid request type" }); break; } callback(id, answer, success); _isPendingRequest = false; }