taneliang / gent Goto Github PK
View Code? Open in Web Editor NEWReusable business logic base layer for GraphQL API servers written in TypeScript+Node.js
License: MIT License
Reusable business logic base layer for GraphQL API servers written in TypeScript+Node.js
License: MIT License
static accessControlRules(police: Police<UserQuery, User>) {
police
// Only allow a user to create/update/delete their own record. This works.
.onCreateUpdateDelete((police) => {
return police.denyIfUnauthenticated().allowWithRestrictedGraphView((vc, query) => {
if (vc instanceof UserViewerContext) {
query.whereIdEquals(vc.user.id);
} else {
throw new Error('Only UserViewerContext supported!');
}
return query;
});
})
// Expectation: For every user record:
// 1. The user should be able to see all their own fields.
// 2. Others can only see an allowed list of fields (e.g. email,
// username).
.onRead((police) => {
// Reality: like the create/update/delete case above, we can only allow
// users to see all fields of their own record, OR allow everyone to see
// that allowed list of fields for all records. We can't have a
// combination of both.
return police.allowWithRestrictedGraphView((vc, query) => {
query.dangerouslyBuildKnexQueryBuilder((kqb) =>
kqb.clearSelect().select('email,username'),
);
return query;
});
});
}
Implement post-query access control rules to filter out unauthorized information.
checkCanSee
method, so confidence level class Police<QueryType extends GentQuery<Model>, Model extends GentModel> {
...
allowWithRestrictedGraphView(
queryBuilder: (vc: ViewerContext, query: QueryType) => QueryType,
postQueryTransform?: (vc: ViewerContext, fetchedModel: Model) => Model | undefined = undefined
): this;
...
}
return police.allowWithRestrictedGraphView(
(vc, query) => query,
(vc, fetchedModel) =>
fetchedModel.ownerId === vc.user.id
? fetchedModel
: _.pick(fetchedModel, ['id', 'email', 'username']),
);
Model
may not be compatible with the transformed type, e.g. we may require name
to be non-nullable in the database, but we may not want to expose name
to end users. Possible solutions:
OutputModel
type. This may be problematic if we still want Police to sometimes output the original type; e.g. we may want to output both User
and OtherUser
types. However, this approach may work if both types are compatible, or if we decouple the storage model type from the business layer's type (and eventually the exposed API type).Somehow implement intent-based access control rules, e.g. getting a list of users' info vs getting one user's info.
Somehow implement query splitting, e.g. splitting the original query for all users into 2 queries, one with the query SELECT <authorized fields>...
and the other SELECT * ... WHERE id=...
.
GentMutator
currently waits for all observer hook promises to resolve before continuing with its next steps. As these hooks should support slow work such as network requests (for logging, cache updates, search index updates, sending emails, etc) or other long-running, non-urgent computations, it may be a good idea to implement a non-blocking async runner that can execute such tasks without blocking the mutator from progressing.
Running hooks in such an async fashion should be optional, as there are many cases where we do want these hooks to block.
scheduler
, a cooperative scheduling system that supports interruption and job priorities. It could possibly be used in Gent to allow our hooks to schedule work to be executed when the server is idle, while remaining responsive to new requests. An introduction to how it's used in React concurrent mode is available in this blog post.Currently, we're using Lodash as it's convenient. However, we want to be a good package with as few dependencies as possible. Lodash is not strictly necessary and should be replaced with plain util functions.
1:M, M:1 currently supported.
Test coverage is a miserable 20%, and we definitely want to increase that. However, as a lot of the code does code generation, the typical unit test approach won't work as that will not test the generated code.
Current wish list:
Currently, we assume that all schemas are stored in a "./src/gents" folder. We need to support multiple schema folders to support larger apps.
gentgen
to look in multiple directories. It is currently hardcoded to "./src/gents" (#3).../<entity class>/
)A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.