Skip to content

Commit

Permalink
Merge pull request #41 from warrant-dev/feat/AddWarrantTokenSupport
Browse files Browse the repository at this point in the history
Add warrant token support
  • Loading branch information
stanleyphu authored Aug 29, 2023
2 parents ea5960c + 5bb0b9c commit 736f597
Show file tree
Hide file tree
Showing 12 changed files with 305 additions and 230 deletions.
6 changes: 6 additions & 0 deletions src/HttpClient.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import ApiError from "./types/ApiError";
import { WarrantRequestOptions } from "./types/WarrantRequestOptions";

const { version } = require("../package.json");

Expand All @@ -20,6 +21,7 @@ export interface HttpClientRequestOptions {
data?: any;
params?: any;
url: string;
options?: WarrantRequestOptions;
}

interface RequestHeaders {
Expand Down Expand Up @@ -107,6 +109,10 @@ export default class ApiClient implements HttpClient {
baseUrl = requestOptions.baseUrl;
}

if (requestOptions?.options?.warrantToken) {
fetchRequestOptions.headers['Warrant-Token'] = requestOptions.options.warrantToken;
}

let requestUrl = `${baseUrl}${requestOptions.url}`;
if (requestOptions?.params) {
const queryParams = new URLSearchParams(requestOptions.params);
Expand Down
27 changes: 15 additions & 12 deletions src/modules/Authorization.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import Feature from "./Feature";
import Permission from "./Permission";
import Check, { AccessCheckRequest, CheckMany, CheckWarrant, FeatureCheck, PermissionCheck } from "../types/Check";
import { WarrantRequestOptions } from "../types/WarrantRequestOptions";
import Warrant, { isSubject, isWarrantObject } from "../types/Warrant";
import WarrantClient from "../WarrantClient";

export default class Authorization {
public static async check(check: Check): Promise<boolean> {
public static async check(check: Check, options: WarrantRequestOptions = {}): Promise<boolean> {
const accessCheckRequest: AccessCheckRequest = {
warrants: [{
object: check.object,
Expand All @@ -16,13 +17,13 @@ export default class Authorization {
debug: check.debug
}
if (WarrantClient.config.authorizeEndpoint) {
return this.edgeAuthorize(accessCheckRequest);
return this.edgeAuthorize(accessCheckRequest, options);
}

return this.authorize(accessCheckRequest);
return this.authorize(accessCheckRequest, options);
}

public static async checkMany(check: CheckMany): Promise<boolean> {
public static async checkMany(check: CheckMany, options: WarrantRequestOptions = {}): Promise<boolean> {
let warrants: CheckWarrant[] = check.warrants.map((warrant) => {
return {
object: warrant.object,
Expand All @@ -38,34 +39,34 @@ export default class Authorization {
}

if (WarrantClient.config.authorizeEndpoint) {
return this.edgeAuthorize(accessCheckRequest);
return this.edgeAuthorize(accessCheckRequest, options);
}

return this.authorize(accessCheckRequest);
return this.authorize(accessCheckRequest, options);
}

public static async hasFeature(featureCheck: FeatureCheck): Promise<boolean> {
public static async hasFeature(featureCheck: FeatureCheck, options: WarrantRequestOptions = {}): Promise<boolean> {
return this.check({
object: new Feature(featureCheck.featureId),
relation: "member",
subject: featureCheck.subject,
context: featureCheck.context,
debug: featureCheck.debug
})
}, options)
}

public static async hasPermission(permissionCheck: PermissionCheck): Promise<boolean> {
public static async hasPermission(permissionCheck: PermissionCheck, options: WarrantRequestOptions = {}): Promise<boolean> {
return this.check({
object: new Permission(permissionCheck.permissionId),
relation: "member",
subject: permissionCheck.subject,
context: permissionCheck.context,
debug: permissionCheck.debug
})
}, options)
}

// Private methods
private static async authorize(accessCheckRequest: AccessCheckRequest): Promise<boolean> {
private static async authorize(accessCheckRequest: AccessCheckRequest, options: WarrantRequestOptions = {}): Promise<boolean> {
try {

const response = await WarrantClient.httpClient.post({
Expand All @@ -74,6 +75,7 @@ export default class Authorization {
...accessCheckRequest,
warrants: this.mapWarrantsForRequest(accessCheckRequest.warrants),
},
options,
});

return response.code === 200;
Expand All @@ -82,7 +84,7 @@ export default class Authorization {
}
}

private static async edgeAuthorize(accessCheckRequest: AccessCheckRequest): Promise<boolean> {
private static async edgeAuthorize(accessCheckRequest: AccessCheckRequest, options: WarrantRequestOptions = {}): Promise<boolean> {
try {
const response = await WarrantClient.httpClient.post({
baseUrl: WarrantClient.config.authorizeEndpoint,
Expand All @@ -91,6 +93,7 @@ export default class Authorization {
...accessCheckRequest,
warrants: this.mapWarrantsForRequest(accessCheckRequest.warrants),
},
options,
});

return response.code === 200;
Expand Down
46 changes: 27 additions & 19 deletions src/modules/Feature.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import WarrantModule from "./WarrantModule";
import WarrantClient from "../WarrantClient";
import { CreateFeatureParams, ListFeatureOptions } from "../types/Feature";
import { WarrantRequestOptions } from "../types/WarrantRequestOptions";
import Warrant, { WarrantObject } from "../types/Warrant";
import { ObjectType } from "../types/ObjectType";

Expand All @@ -14,11 +15,12 @@ export default class Feature implements WarrantObject {
//
// Static methods
//
public static async create(feature: CreateFeatureParams): Promise<Feature> {
public static async create(feature: CreateFeatureParams, options: WarrantRequestOptions = {}): Promise<Feature> {
try {
const response = await WarrantClient.httpClient.post({
url: "/v1/features",
data: feature,
options,
});

return new Feature(response.featureId);
Expand All @@ -27,10 +29,11 @@ export default class Feature implements WarrantObject {
}
}

public static async get(featureId: string): Promise<Feature> {
public static async get(featureId: string, options: WarrantRequestOptions = {}): Promise<Feature> {
try {
const response = await WarrantClient.httpClient.get({
url: `/v1/features/${featureId}`,
options,
});

return new Feature(response.featureId);
Expand All @@ -39,21 +42,23 @@ export default class Feature implements WarrantObject {
}
}

public static async delete(featureId: string): Promise<void> {
public static async delete(featureId: string, options: WarrantRequestOptions = {}): Promise<void> {
try {
return await WarrantClient.httpClient.delete({
url: `/v1/features/${featureId}`,
options,
});
} catch (e) {
throw e;
}
}

public static async listFeatures(listOptions: ListFeatureOptions = {}): Promise<Feature[]> {
public static async listFeatures(listOptions: ListFeatureOptions = {}, options: WarrantRequestOptions = {}): Promise<Feature[]> {
try {
const response = await WarrantClient.httpClient.get({
url: "/v1/features",
params: listOptions,
options,
});

return response.map((feature: Feature) => new Feature(feature.featureId));
Expand All @@ -62,11 +67,12 @@ export default class Feature implements WarrantObject {
}
}

public static async listFeaturesForPricingTier(pricingTierId: string, listOptions: ListFeatureOptions = {}): Promise<Feature[]> {
public static async listFeaturesForPricingTier(pricingTierId: string, listOptions: ListFeatureOptions = {}, options: WarrantRequestOptions = {}): Promise<Feature[]> {
try {
const response = await WarrantClient.httpClient.get({
url: `/v1/pricing-tiers/${pricingTierId}/features`,
params: listOptions,
options,
});

return response.map((feature: Feature) => new Feature(feature.featureId));
Expand All @@ -75,7 +81,7 @@ export default class Feature implements WarrantObject {
}
}

public static async assignFeatureToPricingTier(pricingTierId: string, featureId: string): Promise<Warrant> {
public static async assignFeatureToPricingTier(pricingTierId: string, featureId: string, options: WarrantRequestOptions = {}): Promise<Warrant> {
return WarrantModule.create({
object: {
objectType: ObjectType.Feature,
Expand All @@ -86,10 +92,10 @@ export default class Feature implements WarrantObject {
objectType: ObjectType.PricingTier,
objectId: pricingTierId,
}
});
}, options);
}

public static async removeFeatureFromPricingTier(pricingTierId: string, featureId: string): Promise<void> {
public static async removeFeatureFromPricingTier(pricingTierId: string, featureId: string, options: WarrantRequestOptions = {}): Promise<void> {
return WarrantModule.delete({
object: {
objectType: ObjectType.Feature,
Expand All @@ -100,14 +106,15 @@ export default class Feature implements WarrantObject {
objectType: ObjectType.PricingTier,
objectId: pricingTierId,
}
});
}, options);
}

public static async listFeaturesForTenant(tenantId: string, listOptions: ListFeatureOptions = {}): Promise<Feature[]> {
public static async listFeaturesForTenant(tenantId: string, listOptions: ListFeatureOptions = {}, options: WarrantRequestOptions = {}): Promise<Feature[]> {
try {
const response = await WarrantClient.httpClient.get({
url: `/v1/tenants/${tenantId}/features`,
params: listOptions,
options,
});

return response.map((feature: Feature) => new Feature(feature.featureId));
Expand All @@ -116,7 +123,7 @@ export default class Feature implements WarrantObject {
}
}

public static async assignFeatureToTenant(tenantId: string, featureId: string): Promise<Warrant> {
public static async assignFeatureToTenant(tenantId: string, featureId: string, options: WarrantRequestOptions = {}): Promise<Warrant> {
return WarrantModule.create({
object: {
objectType: ObjectType.Feature,
Expand All @@ -127,10 +134,10 @@ export default class Feature implements WarrantObject {
objectType: ObjectType.Tenant,
objectId: tenantId,
}
});
}, options);
}

public static async removeFeatureFromTenant(tenantId: string, featureId: string): Promise<void> {
public static async removeFeatureFromTenant(tenantId: string, featureId: string, options: WarrantRequestOptions = {}): Promise<void> {
return WarrantModule.delete({
object: {
objectType: ObjectType.Feature,
Expand All @@ -141,14 +148,15 @@ export default class Feature implements WarrantObject {
objectType: ObjectType.Tenant,
objectId: tenantId,
}
});
}, options);
}

public static async listFeaturesForUser(userId: string, listOptions: ListFeatureOptions = {}): Promise<Feature[]> {
public static async listFeaturesForUser(userId: string, listOptions: ListFeatureOptions = {}, options: WarrantRequestOptions = {}): Promise<Feature[]> {
try {
const response = await WarrantClient.httpClient.get({
url: `/v1/users/${userId}/features`,
params: listOptions,
options,
});

return response.map((feature: Feature) => new Feature(feature.featureId));
Expand All @@ -157,7 +165,7 @@ export default class Feature implements WarrantObject {
}
}

public static async assignFeatureToUser(userId: string, featureId: string): Promise<Warrant> {
public static async assignFeatureToUser(userId: string, featureId: string, options: WarrantRequestOptions = {}): Promise<Warrant> {
return WarrantModule.create({
object: {
objectType: ObjectType.Feature,
Expand All @@ -168,10 +176,10 @@ export default class Feature implements WarrantObject {
objectType: ObjectType.User,
objectId: userId,
}
});
}, options);
}

public static async removeFeatureFromUser(userId: string, featureId: string): Promise<void> {
public static async removeFeatureFromUser(userId: string, featureId: string, options: WarrantRequestOptions = {}): Promise<void> {
return WarrantModule.delete({
object: {
objectType: ObjectType.Feature,
Expand All @@ -182,7 +190,7 @@ export default class Feature implements WarrantObject {
objectType: ObjectType.User,
objectId: userId,
}
});
}, options);
}

// WarrantObject methods
Expand Down
Loading

0 comments on commit 736f597

Please sign in to comment.