Skip to content
This repository was archived by the owner on May 16, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 38 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ thiserror = "1.0.24"
tokio = { version = "1.9.0", features = [ "full" ] }
tonic = "0.5.2"
tracing = "0.1"
tracing-appender = "0.1"
tracing-appender = "0.2"
tracing-subscriber = "0.2"
ttl_cache = "0.5.1"
uuid = { version = "0.8.2", features = [ "serde" ] }
Expand Down
4 changes: 3 additions & 1 deletion examples/js/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ class Client {
}

async balanceUpdate(transactionAdmin, user_id, asset, business, business_id, delta, detail) {
let meta = transactionAdmin === null ? {} : await this.auth.getAuthTokenMeta(transactionAdmin);

return await this.client.BalanceUpdate(
{
user_id,
Expand All @@ -97,7 +99,7 @@ class Client {
delta,
detail: JSON.stringify(detail),
},
await this.auth.getAuthTokenMeta(transactionAdmin)
meta
);
}
roundOrderInput(market, amount, price) {
Expand Down
124 changes: 102 additions & 22 deletions examples/js/tests/authorization.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { fee, market, ORDER_SIDE_BID, ORDER_TYPE_LIMIT, TestUser } from "../config"; // dotenv
import { defaultClient as client, defaultClient as grpcClient } from "../client";
import { defaultClient as grpcClient } from "../client";
import { defaultRESTClient as restClient } from "../RESTClient";
import * as assert from "assert";
import { Authentication } from "../authentication";
import { depositAssets } from "../exchange_helper";

const GRPC_PERMISSION_DENIED_CODE = 7;
const GRPC_PERMISSION_DENIED_TEXT = "Requires admin role.";
const GRPC_DEPOSIT_PERMISSION_DENIED_TEXT = "Requires deposit-admin role.";
const GRPC_WITHDRAWAL_PERMISSION_DENIED_TEXT = "Requires withdrawal-admin role.";
const GRPC_TOKEN_NOT_FOUND_CODE = 16;
const GRPC_TOKEN_NOT_FOUND_TEXT = "Token not found";
const GRPC_INVALID_TOKEN_CODE = 16;
Expand Down Expand Up @@ -105,16 +107,7 @@ async function grpcRejectUserWithoutToken() {
}

try {
// surpress logging
let console_log = console.log;
console.log = function () {
/* do nothing */
};

await depositAssets({ USDT: "100.0", ETH: "50.0" }, process.env.KC_USER1_ID, NON_EXISTANT_USER);

// reactivate logging
console.log = console_log;
throw Error("GRPC call must fail as no authentication token is provided!");
} catch (e) {
grpcAssertErrorNoTokenProvided(e);
Expand Down Expand Up @@ -180,24 +173,95 @@ async function grpcPermitAccessToRegularUser() {
await grpcClient.balanceQueryWithValidToken();
await grpcClient.orderCancelAll(TestUser.USER1, market);

// surpress logging
let console_log = console.log;
console.log = function () {
/* do nothing */
};

// === SETTING UP MARKET DATA THAT IS LATER BEING USED FOR orderDetail TESTS. === //
await depositAssets({ USDT: "100.0", ETH: "50.0" }, process.env.KC_USER1_ID, TestUser.DEPOSIT_ADMIN);
await grpcClient.orderPut(TestUser.USER1, market, ORDER_SIDE_BID, ORDER_TYPE_LIMIT, "10", "1.1", fee, fee);
await batchOrderPut(TestUser.USER1);

// reactivate logging
console.log = console_log;

await grpcClient.orderCancel(TestUser.USER1, market, 2);
await grpcClient.orderQuery(TestUser.USER1, market);
}

async function grpcTestDepositAccess() {
// Deposit should begranted to the deposit admin user.
await depositAssets({ USDT: "100.0", ETH: "50.0" }, process.env.KC_USER1_ID, TestUser.DEPOSIT_ADMIN);

try {
await depositAssets({ USDT: "100.0", ETH: "50.0" }, process.env.KC_USER1_ID, TestUser.ADMIN);
throw Error("Admin must not be able to deposit funds");
} catch (e) {
grpcAssertErrorDepositPermissionDenied(e);
}

try {
await depositAssets({ USDT: "100.0", ETH: "50.0" }, process.env.KC_USER1_ID, TestUser.WITHDRAWAL_ADMIN);
throw Error("Withdrawal Admin must not be able to deposit funds");
} catch (e) {
grpcAssertErrorDepositPermissionDenied(e);
}

try {
await depositAssets({ USDT: "100.0", ETH: "50.0" }, process.env.KC_USER1_ID, TestUser.USER1);
throw Error("Regular user must not be able to deposit funds");
} catch (e) {
grpcAssertErrorDepositPermissionDenied(e);
}

try {
await depositAssets({ USDT: "100.0", ETH: "50.0" }, process.env.KC_USER1_ID, TestUser.USER1);
throw Error("Regular user must not be able to deposit funds");
} catch (e) {
grpcAssertErrorDepositPermissionDenied(e);
}

try {
await depositAssets({ USDT: "100.0", ETH: "50.0" }, process.env.KC_USER1_ID, null);
throw Error("Anonymous must not be able to deposit funds");
} catch (e) {
grpcAssertErrorNoTokenProvided(e);
}
}

async function grpcTestWithdrawalAccess() {
// Deposit should begranted to the withdrawal admin user.
await depositAssets({ USDT: "-100.0", ETH: "-50.0" }, process.env.KC_USER1_ID, TestUser.WITHDRAWAL_ADMIN);

try {
await depositAssets({ USDT: "-100.0", ETH: "-50.0" }, process.env.KC_USER1_ID, TestUser.ADMIN);
throw Error("Admin must not be able to withdraw funds");
} catch (e) {
grpcAssertErrorWithdrawalPermissionDenied(e);
}

try {
await depositAssets({ USDT: "-100.0", ETH: "-50.0" }, process.env.KC_USER1_ID, TestUser.DEPOSIT_ADMIN);
throw Error("Deposit Admin must not be able to withdraw funds");
} catch (e) {
grpcAssertErrorWithdrawalPermissionDenied(e);
}

try {
await depositAssets({ USDT: "-100.0", ETH: "-50.0" }, process.env.KC_USER1_ID, TestUser.USER1);
throw Error("Regular user must not be able to withdraw funds");
} catch (e) {
grpcAssertErrorWithdrawalPermissionDenied(e);
}

try {
await depositAssets({ USDT: "-100.0", ETH: "-50.0" }, process.env.KC_USER1_ID, TestUser.USER1);
throw Error("Regular user must not be able to withdraw funds");
} catch (e) {
grpcAssertErrorWithdrawalPermissionDenied(e);
}

try {
await depositAssets({ USDT: "-100.0", ETH: "-50.0" }, process.env.KC_USER1_ID, null);
throw Error("Anonymous must not be able to withdraw funds");
} catch (e) {
grpcAssertErrorNoTokenProvided(e);
}
}

async function grpcTestPublicEndpoints() {
// should work without authentication ...
await grpcClient.assetList({});
Expand Down Expand Up @@ -391,6 +455,16 @@ function grpcAssertErrorPermissionDenied(error) {
assert.equal(error.details, GRPC_PERMISSION_DENIED_TEXT);
}

function grpcAssertErrorDepositPermissionDenied(error) {
assert.equal(error.code, GRPC_PERMISSION_DENIED_CODE);
assert.equal(error.details, GRPC_DEPOSIT_PERMISSION_DENIED_TEXT);
}

function grpcAssertErrorWithdrawalPermissionDenied(error) {
assert.equal(error.code, GRPC_PERMISSION_DENIED_CODE);
assert.equal(error.details, GRPC_WITHDRAWAL_PERMISSION_DENIED_TEXT);
}

function grpcAssertErrorNoTokenProvided(error) {
assert.equal(error.code, GRPC_TOKEN_NOT_FOUND_CODE);
assert.equal(error.details, GRPC_TOKEN_NOT_FOUND_TEXT);
Expand All @@ -417,10 +491,14 @@ function restAssertAuthenticationNotSatisfactory(error) {
}

async function main() {
// disable logging
// eslint-disable-next-line @typescript-eslint/no-empty-function
console.log = () => {};

let auth = new Authentication();

try {
console.log("GRPC authentication");
console.info("GRPC authentication");
await grpcPermitAdminAccess();
await grpcRejectUserAccessingAdminCalls();
await grpcRejectAnonymousAccessingAdminCalls();
Expand All @@ -429,8 +507,10 @@ async function main() {
await grpcRejectUserWithInvalidSignatureToken();
await grpcRejectUserWithExpiredToken();
await grpcPermitAccessToRegularUser();
await grpcTestDepositAccess();
await grpcTestWithdrawalAccess();
await grpcTestPublicEndpoints();
console.log("REST authentication");
console.info("REST authentication");
await restRejectUserWithoutToken();
await restRejectUserWithInvalidToken();
await restRejectUserWithInvalidToken2();
Expand All @@ -441,7 +521,7 @@ async function main() {
await restTestRegularEndpoints(auth);
await testAdminEndpoints(auth);

console.log("Authorization tests successful!");
console.info("Authorization tests successful!");
} catch (error) {
console.error("Caught error:", error);
process.exit(1);
Expand Down