Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
psanders committed Jun 18, 2022
1 parent ac439cb commit 8336e40
Show file tree
Hide file tree
Showing 36 changed files with 444 additions and 8,688 deletions.
7 changes: 7 additions & 0 deletions mods/limiter/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
node_modules
.nyc_output
coverage
src
test
*.log
*.ts
25 changes: 25 additions & 0 deletions mods/limiter/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
##
## Build and pack the service
##
FROM fonoster/base as builder

COPY . /scripts
RUN ./install.sh

##
## Runner
##
FROM fonoster/base as runner

COPY --from=builder /scripts/fonoster-* .

RUN apk add --no-cache --update git tini npm nodejs \
&& npm install -g fonoster-*.tgz \
&& apk del npm git

USER fonoster

CMD ["run_limiter"]

HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
CMD [ "healthcheck_limiter" ]
3 changes: 2 additions & 1 deletion mods/limiter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"scripts": {
"prebuild": "rimraf ./dist tsconfig.tsbuildinfo",
"build": "tsc -b tsconfig.json",
"postbuild": "cp -a ./src/service/protos/ ./dist/service/protos",
"start": "cross-env NODE_ENV=dev nodemon src/service/runner"
},
"bin": {
Expand Down Expand Up @@ -43,6 +42,8 @@
"url": "https://github.com/fonoster/fonoster/issues"
},
"dependencies": {
"@fonoster/auth": "^0.3.9",
"@fonoster/users": "^0.3.9",
"@fonoster/projects": "^0.3.9",
"@fonoster/common": "^0.3.9",
"@fonoster/errors": "^0.3.9",
Expand Down
18 changes: 18 additions & 0 deletions mods/limiter/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (C) 2021 by Fonoster Inc (https://fonoster.com)
* http://github.com/fonoster/fonoster
*
* This file is part of Fonoster
*
* Licensed under the MIT License (the "License");
* you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
3 changes: 3 additions & 0 deletions mods/limiter/src/service/healthcheck.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env node
//import {healthcheck} from "@fonoster/common";
//healthcheck();
93 changes: 93 additions & 0 deletions mods/limiter/src/service/limiter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Copyright (C) 2022 by Fonoster Inc (https://fonoster.com)
* http://github.com/fonoster/fonoster
*
* This file is part of Fonoster
*
* Licensed under the MIT License (the "License");
* you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* https://opensource.org/licenses/MIT
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable require-jsdoc */
import grpc from "@grpc/grpc-js";
import {
CheckAuthorizedRequest,
CheckAuthorizedResponse
} from "@fonoster/auth/dist/service/protos/auth_pb";
import {
ILimiterServer,
ILimiterService,
LimiterService
} from "@fonoster/auth/dist/service/protos/auth_grpc_pb";
import {getAccessKeyId, getRedisConnection, routr} from "@fonoster/core";
import {
getLimiters,
getLimitForPath,
getResourceCount,
getUserByAccessKeyId
} from "../utils/utils";
import {Limiter} from "./types";
import {ErrorCodes, FonosterError} from "@fonoster/errors";
import {UserStatus} from "@fonoster/users/dist/service/types";

const redis = getRedisConnection();
const limiters: Limiter[] = getLimiters();

class LimiterServer implements ILimiterServer {
[name: string]: grpc.UntypedHandleCall;
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
async checkAuthorized(
call: grpc.ServerUnaryCall<CheckAuthorizedRequest, CheckAuthorizedResponse>,
callback: grpc.sendUnaryData<CheckAuthorizedResponse>
) {
const accessKeyId = getAccessKeyId(call);
const user = await getUserByAccessKeyId(redis)(accessKeyId);
const limit = getLimitForPath(limiters)(
user.getLimiter(),
call.request.getPath()
);

const resourceCount = await getResourceCount(redis, routr)(
accessKeyId,
limit?.resource
);

if (limit) {
const userStatus = user.getStatus()
? user.getStatus()
: UserStatus.ACTIVE;

if (limit.allowedForStatus.toLowerCase() != userStatus.toLowerCase()) {
return callback(
new FonosterError(
`Permission denied due to account status (${user.getStatus()})`,
ErrorCodes.PERMISSION_DENIED
)
);
}

if (resourceCount >= limit.limit) {
return callback(
new FonosterError(
`Permission denied. Your account only allows for ${limit.limit} ${limit.resource}s.`,
ErrorCodes.PERMISSION_DENIED
)
);
}
}

const response = new CheckAuthorizedResponse();
response.setAuthorized(true);
callback(null, response);
}
}

export {LimiterServer as default, ILimiterService, LimiterService};
1 change: 0 additions & 1 deletion mods/limiter/src/service/protos/common_grpc_pb.js

This file was deleted.

54 changes: 0 additions & 54 deletions mods/limiter/src/service/protos/common_pb.d.ts

This file was deleted.

Loading

0 comments on commit 8336e40

Please sign in to comment.