Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

支持 casbin #149

Closed
wants to merge 3 commits into from
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
8 changes: 8 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"cSpell.words": [
"Casbin",
"CASBINCONNECTION",
"Prioritizeable",
"typeorm"
]
}
3 changes: 3 additions & 0 deletions configs/root-compilation.tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@
{
"path": "../packages/typeorm/compile.tsconfig.json"
},
{
"path": "../packages/casbin/compile.tsconfig.json"
},
{
"path": "../packages/vercel-adapter/compile.tsconfig.json"
},
Expand Down
25 changes: 25 additions & 0 deletions examples/casbin-app/.github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Malagu Deploy

on: push

jobs:
malagu-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup node
uses: actions/setup-node@v1
with:
node-version: '12'
- uses: bahmutov/npm-install@v1
- run: npm run lint --if-present
- run: npm test
- if: ${{ github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' }}
env: ${{ secrets }}
run: npx malagu deploy -m prod
- if: ${{ github.ref == 'refs/heads/pre' }}
env: ${{ secrets }}
run: npx malagu deploy -m pre
- if: ${{ github.ref != 'refs/heads/master' && github.ref == 'refs/heads/main' && github.ref != 'refs/heads/pre' }}
env: ${{ secrets }}
run: npx malagu deploy -m test
22 changes: 22 additions & 0 deletions examples/casbin-app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.DS_Store
node_modules
dist
lib
.malagu
.env
*.log
.idea
.metadata
*.iml
jdt.ls-java-project
lerna-debug.log
.nyc_output
coverage
errorShots
.browser_modules
**/docs/api
package-backup.json
.history
.Trash-*
packages/plugin/typedoc
plugins
23 changes: 23 additions & 0 deletions examples/casbin-app/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Malagu Debug",
"request": "launch",
"runtimeArgs": [
"malagu",
"serve"
],
"runtimeExecutable": "npx",
"skipFiles": [
"<node_internals>/**"
],
"env": {
"NODE_ENV": "development"
},
"internalConsoleOptions": "openOnSessionStart",
"outputCapture": "std",
"type": "pwa-node"
}
]
}
94 changes: 94 additions & 0 deletions examples/casbin-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# 开发说明

## 安装依赖

以下使用 yarn 工具来说明,你也可以使用 npm。

```bash
# 通过 malagu init 初始化应用的时候已经自动安装了依赖,所以你只需要安装你额外需要的依赖即可

$ yarn add xxxx
```

## 本地运行

```shell
# 启动本地服务,端口默认 3000
# 在终端中会输出本地服务的 URL 链接

$ yarn start # 或者执行 malagu serve 命令
```

## 构建部署

模板默认提供了四套隔离环境:本地(local)、测试(test)、预发(pre)、线上(prod)。每个环境对于这一个 malagu 配置文件(可选),类似 malagu-test.yml。而 malagu.yml 文件一般用于放所有环境的公共配置。第一次部署的时候可能会提示你填写相关云厂商 ak 信息。如果是 Vercel 云平台的模板,会提示你需要登录到 Vercel 平台。你也可以在项目通过 .env 提供云厂商的 ak 信息。

```bash

$ malagu deploy -m scf # 部署到腾讯云函数测试环境
$ malagu deploy -m scf -m test # 部署到腾讯云测试环境
$ malagu deploy -m scf -m pre # 部署到腾讯云预发环境
$ malagu deploy -m scf -m prod # 部署到腾讯云线上环境

```

## 关于 Malagu Framework

Malagu 是基于 TypeScript 的 Serverless First、组件化、平台无关的渐进式应用框架。


## 特征

- 约定大于配置,零配置,开箱即用
- TypeScript 版 Spring Boot
- Serverless First
- 平台不锁定
- 支持前后端一体化,前端框架不锁定
- 支持微服务
- 组件化,渐进式
- 命令行工具插件化
- 依赖注入
- 面向切面编程(AOP)
- 集成了流行的 ORM 框架,使用装饰器声明式事务管理
- 支持 OIDC 认证
- 支持 OAuth2 授权
- 使用 rxjs 管理状态
- 提供 REST 和 RPC 两种接口风格

Malagu 名字由来:在我的家乡,谐音“吗啦咕”是小石头的意思,小石头堆砌起来可以建成高楼大厦、道路桥梁,而 Malagu 组件编排可以实现千变万化的应用。

## 快速开始

```bash
# 安装命令行工具
npm install -g @malagu/cli

# 初始化
malagu init project-name
cd project-name # 进入项目根目录

# 运行
malagu serve

# 部署
malagu deploy
```

[![Quick Start](https://asciinema.org/a/474104.svg)](https://asciinema.org/a/474104?speed=2.5&autoplay=1)

### 文档

- [介绍](https://malagu.cellbang.com/guide/%E4%BB%8B%E7%BB%8D)
- [创建第一个应用](https://malagu.cellbang.com/guide/%E5%88%9B%E5%BB%BA%E7%AC%AC%E4%B8%80%E4%B8%AA%E5%BA%94%E7%94%A8)
- [命令行工具](https://malagu.cellbang.com/guide/%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7)
- [控制器](https://malagu.cellbang.com/guide/%E6%8E%A7%E5%88%B6%E5%99%A8)
- [数据库操作](https://malagu.cellbang.com/guide/%E6%95%B0%E6%8D%AE%E5%BA%93typeorm)
- [微服务](https://malagu.cellbang.com/dev/%E5%BE%AE%E6%9C%8D%E5%8A%A1)
- [认证与授权](https://malagu.cellbang.com/guide/%E8%AE%A4%E8%AF%81%E4%B8%8E%E6%8E%88%E6%9D%83)
- [云平台适配](https://malagu.cellbang.com/cloud/%E4%BA%91%E5%B9%B3%E5%8F%B0%E9%80%82%E9%85%8D)
- [依赖注入](https://malagu.cellbang.com/guide/%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5)
- [组件设计](https://malagu.cellbang.com/guide/%E7%BB%84%E4%BB%B6%E8%AE%BE%E8%AE%A1)
- [前端架构](https://malagu.cellbang.com/guide/%E5%89%8D%E7%AB%AF%E6%9E%B6%E6%9E%84)
- [React 开发](https://malagu.cellbang.com/dev/react)
- [前后端一体化开发](https://malagu.cellbang.com/dev/%E5%89%8D%E5%90%8E%E7%AB%AF%E4%B8%80%E4%BD%93%E5%8C%96%E5%BC%80%E5%8F%91)

16 changes: 16 additions & 0 deletions examples/casbin-app/malagu.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
targets:
- backend

backend:
malagu:
casbin:
dataSource: "src/utils/casbin.conf" # 云端建议使用 层 来存放此文件
typeorm:
ormConfig:
- type: "mysql"
name: "Casbin"
host: "localhost"
port: 3306
username: "root"
password: "12345678"
database: "casbin"
30 changes: 30 additions & 0 deletions examples/casbin-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"private": true,
"name": "@malagu/example-casbin-app",
"keywords": [
"malagu-component"
],
"version": "2.26.2",
"license": "MIT",
"files": [
"lib",
"src"
],
"dependencies": {
"@malagu/core": "2.26.2",
"@malagu/mvc": "2.26.2",
"@malagu/casbin": "2.26.2"
},
"devDependencies": {
"@malagu/cli": "2.26.2"
},
"scripts": {
"clean": "rimraf lib dist .malagu",
"build": "malagu build",
"start": "malagu serve",
"deploy": "malagu deploy -m scf -m test",
"deploy:test": "malagu deploy -m scf -m test",
"deploy:pre": "malagu deploy -m scf -m pre",
"deploy:prod": "malagu deploy -m scf -m prod"
}
}
17 changes: 17 additions & 0 deletions examples/casbin-app/src/home-controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Controller, Get } from "@malagu/mvc/lib/node";
import { EnforcerInstance } from "@malagu/casbin/lib/common/";

@Controller()
export class HomeController {
@Get()
async home() {
// const e = EnforcerInstance;
// Modify the policy.
// await e.addPolicy("admin", "domain1", "data1", "read");
// await e.removePolicy(...);

// Save the policy back to DB.
// await e.savePolicy();
return "Welcome to Malagu Casbin!";
}
}
18 changes: 18 additions & 0 deletions examples/casbin-app/src/middleware/advice/advice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Aspect, MethodBeforeAdvice } from "@malagu/core";
import { AOP_POINTCUT } from "@malagu/web";

const pointcut = AOP_POINTCUT;

@Aspect({ id: MethodBeforeAdvice, pointcut })
export class CustomMethodBeforeAdvice implements MethodBeforeAdvice {
before(
method: string | number | symbol,
args: any[],
target: any
): Promise<void> {
console.log(
`${method.toString()} | QueryValue | ${JSON.stringify(args)}`
);
return Promise.resolve(undefined);
}
}
20 changes: 20 additions & 0 deletions examples/casbin-app/src/middleware/advice/error-log.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Aspect } from "@malagu/core";
import { AOP_POINTCUT } from "@malagu/web";
import { AfterThrowsAdvice } from "../../utils/advice-util";

const pointcut = AOP_POINTCUT;

@Aspect({ id: AfterThrowsAdvice, pointcut })
export class CustomAfterThrowsAdvice implements AfterThrowsAdvice {
afterThrows(
returnValue: any,
error: any,
method: string | number | symbol,
args: any[],
target: any
): Promise<void> {
returnValue.message = error.message;
console.log(`Error | ${method.toString()} | ${error}`);
return Promise.resolve(undefined);
}
}
3 changes: 3 additions & 0 deletions examples/casbin-app/src/middleware/advice/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './advice';
export * from './error-log';
export * from './return-advice';
21 changes: 21 additions & 0 deletions examples/casbin-app/src/middleware/advice/return-advice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { AfterReturningAdvice, Aspect, Autowired, Value } from "@malagu/core";
import { AOP_POINTCUT } from "@malagu/web";

const pointcut = AOP_POINTCUT;

@Aspect({ id: AfterReturningAdvice, pointcut })
export class CustomAfterAdvice implements AfterReturningAdvice {
afterReturning(
returnValue: any,
method: string | number | symbol,
args: any[],
target: any
) {
console.log(
`${method.toString()} | ReturnValue | ${JSON.stringify(
returnValue
)}`
);
return returnValue;
}
}
39 changes: 39 additions & 0 deletions examples/casbin-app/src/middleware/casbin/casbin-manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Component, Autowired, Prioritizeable } from "@malagu/core";
import { postConstruct } from "inversify";
import { CasbinManager, CasbinProvider } from "./casbin-protocol";

@Component(CasbinManager)
export class CasbinManagerImpl implements CasbinManager {
protected prioritized: CasbinProvider[];

@Autowired(CasbinProvider)
protected readonly CasbinProviders: CasbinProvider[];

@postConstruct()
async init() {
this.prioritized = Prioritizeable.prioritizeAllSync(
this.CasbinProviders
).map((c) => c.value);
}

async authenticate(next: () => Promise<void>): Promise<void> {
for (const authenticationProvider of this.prioritized) {
try {
if (await authenticationProvider.support()) {
await authenticationProvider.authenticate();
}
} catch (error) {
throw error;
}
}
}

async support(): Promise<boolean> {
for (const CasbinProvider of this.prioritized) {
if (await CasbinProvider.support()) {
return true;
}
}
return false;
}
}
36 changes: 36 additions & 0 deletions examples/casbin-app/src/middleware/casbin/casbin-middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Middleware, Context } from "@malagu/web/lib/node";
import { Autowired, Component } from "@malagu/core";
import { CasbinManager } from "./casbin-protocol";
import { SESSION_MIDDLEWARE_PRIORITY } from "@malagu/web/lib/node/session/session-protocol";

@Component(Middleware)
export class CasbinMiddleware implements Middleware {
@Autowired(CasbinManager)
protected readonly casbinManager: CasbinManager;

async handle(ctx: Context, next: () => Promise<void>): Promise<void> {
if (await this.casbinManager.support()) {
try {
await this.casbinManager.authenticate(next);
} catch (error) {
console.log(
`Error | ${ctx.request.path.toString()} | ${error}`
);

ctx.status = 200;
ctx.response.setHeader("Content-Type", "application/json");
ctx.response.end(
JSON.stringify({
code: 1,
message: error.message,
type: "error",
})
);
return;
}
}
await next();
}

readonly priority = SESSION_MIDDLEWARE_PRIORITY - 300;
}
Loading