Skip to content

Commit

Permalink
support for Abstract Service and Controller in MongoDB Framework #831 (
Browse files Browse the repository at this point in the history
…#832)

* update

* The vertices of the graph support the map data structure clsoe(#810)

* upport for Abstract Service and Controller in MongoDB Framework #831
  • Loading branch information
goodjava authored Apr 23, 2024
1 parent f8cda80 commit 7d74352
Show file tree
Hide file tree
Showing 19 changed files with 823 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@
import com.xiaomi.youpin.docean.plugin.config.Config;
import dev.morphia.Datastore;
import dev.morphia.Morphia;
import dev.morphia.mapping.Mapper;
import dev.morphia.mapping.MapperOptions;
import lombok.extern.slf4j.Slf4j;

import java.util.Set;
Expand All @@ -41,24 +39,12 @@ public class MongodbPlugin implements IPlugin {
@Override
public void init(Set<? extends Class<?>> classSet, Ioc ioc) {
log.info("init mongodb plugin");
MongoDb mongoDb = new MongoDb();
Config config = ioc.getBean(Config.class);
mongoDb.setMongoDbClient(config.get("mongodb.client", ""));
mongoDb.setMongoDatabase(config.get("mongodb.database", ""));
mongoDb.setCatEnabled(config.get("mongodb.cat.enabled", "false").equals("true"));
mongoDb.init();
ioc.putBean(mongoDb);


MongoClient mongoClient = MongoClients.create(mongoDb.getMongoDbClient());
Datastore datastore = Morphia.createDatastore(mongoClient, mongoDb.getMongoDatabase());


MongoClient mongoClient = MongoClients.create(config.get("mongodb.client", ""));
Datastore datastore = Morphia.createDatastore(mongoClient, config.get("mongodb.database", ""));
String packagePath = config.get("mongodb.package", "run.mone.bo");
datastore.getMapper().mapPackage(packagePath);
datastore.ensureIndexes();


ioc.putBean(Datastore.class.getName(), datastore);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright 2020 Xiaomi
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/

package run.mone.auth;

import java.lang.annotation.*;

/**
* @author [email protected]
* @date 2020/7/5
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Auth {

String name() default "name";

String role() default "admin";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright 2020 Xiaomi
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* 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.
*/

package run.mone.auth;

import com.xiaomi.youpin.docean.Ioc;
import com.xiaomi.youpin.docean.anno.RequestMapping;
import com.xiaomi.youpin.docean.aop.ProceedingJoinPoint;
import com.xiaomi.youpin.docean.aop.anno.Aspect;
import com.xiaomi.youpin.docean.aop.anno.Before;
import com.xiaomi.youpin.docean.common.StringUtils;
import com.xiaomi.youpin.docean.mvc.ContextHolder;
import com.xiaomi.youpin.docean.mvc.MvcContext;
import lombok.extern.slf4j.Slf4j;
import run.mone.bo.PathAuth;
import run.mone.bo.User;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.concurrent.ConcurrentMap;

/**
* @author [email protected]
*/
@Aspect
@Slf4j
public class AuthAop {

/**
* 在方法执行前进行权限验证的切面方法
* 根据方法上的 @Auth 注解和当前用户的角色进行权限验证
* 如果用户没有相应的权限,则抛出 RuntimeException
* 同时记录了一些日志信息,包括用户名、角色、请求路径等
*/
@Before(anno = Auth.class)
public void before(ProceedingJoinPoint point) {
log.info("before:" + Arrays.toString(point.getArgs()));
MvcContext context = ContextHolder.getContext().get();
User user = (User) context.session().getAttribute("user");
Method method = point.getMethod();
RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
log.info("name:{} role:{} path:{}", user.getUsername(), user.getRole(), requestMapping.path());
Auth auth = method.getAnnotation(Auth.class);

ConcurrentMap<String, PathAuth> map = Ioc.ins().getBean("authMap");
String path = context.getPath();
//这里其实是数据库设置的(每次启动抓取一次)
PathAuth pa = map.get(path);
log.info("{}", pa);

String role = auth.role();
if (null != pa) {
if (StringUtils.isNotEmpty(pa.getRole())) {
role = pa.getRole();
}
}

//必须有后台管理权限
if (role.equals("admin")) {
if (null == user || !user.getRole().equals("admin")) {
throw new RuntimeException("role error");
}
}
//必须登录
if (role.equals("user")) {
if (null == user) {
throw new RuntimeException("role error");
}
}

}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package run.mone.auth;

import com.xiaomi.youpin.docean.Ioc;
import com.xiaomi.youpin.docean.listener.Listener;
import com.xiaomi.youpin.docean.listener.event.Event;
import com.xiaomi.youpin.docean.listener.event.EventType;
import com.xiaomi.youpin.docean.mvc.HttpRequestMethod;
import dev.morphia.Datastore;
import dev.morphia.query.filters.Filters;
import lombok.extern.slf4j.Slf4j;
import run.mone.bo.PathAuth;

import java.lang.reflect.Method;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
* @author [email protected]
* @date 2024/4/23 09:30
*/
@Slf4j
public class AuthListener implements Listener {

ConcurrentMap<String, PathAuth> map = new ConcurrentHashMap<>();

public AuthListener(ConcurrentMap<String, PathAuth> map) {
this.map = map;
}

/**
* 重写onEvent方法,用于处理事件
* 如果事件类型为initControllerFinish,则获取事件数据中的请求方法映射
* 遍历请求方法映射,获取每个请求方法的路径和注解信息
* 根据注解信息确定该路径所需的角色权限
* 如果数据库中不存在该路径的权限记录,则创建一条新记录并插入数据库
* 将路径和权限记录存入map中
*/
@Override
public void onEvent(Event event) {
if (event.getEventType().equals(EventType.initControllerFinish)) {
ConcurrentHashMap<String, HttpRequestMethod> requestMethodMap = event.getData();
log.info("map size:{}", requestMethodMap.size());
Datastore datastore = Ioc.ins().getBean(Datastore.class);
requestMethodMap.values().forEach(it -> {
try {
String path = it.getPath();
Method method = it.getMethod();
Auth auth = method.getAnnotation(Auth.class);
String role = "user";
PathAuth pa = datastore.find(PathAuth.class).filter(Filters.eq("path", path)).first();
if (null == pa) {
if (null != auth) {
role = auth.role();
}
pa = PathAuth.builder().path(path).role(role).build();
datastore.insert(pa);
}
map.put(path, pa);
} catch (Throwable ex) {
ex.printStackTrace();
}
});
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package run.mone.bo;

/**
* @author [email protected]
* @date 2024/4/19 23:10
*/
public interface MongoBo {

String getId();

default String getUid() {
return "";
}

default void setUid(String uid) {

}

int getVersion();

void setState(int state);

void setUtime(long utime);

void setCtime(long ctime);

void setVersion(int version);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package run.mone.bo;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
* @author [email protected]
* @date 2024/4/19 22:36
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Page<T> {

private List<T> content;
private int page;
private int size;
private long total;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package run.mone.bo;

import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* @author [email protected]
* @date 2024/4/22 21:35
*/
@Entity("pathAuth")
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PathAuth {

@Id
private String id;

private String path;

private String role;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package run.mone.bo;

import dev.morphia.annotations.Entity;
import dev.morphia.annotations.Id;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* 用户
*
* @author mone
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity("user")
public class User implements MongoBo{

@Id
private String id;

//用户名
private String username;

//密码(加密存储)
private String password;

//角色 (user admin)
private String role;

//邮箱地址
private String email;

//手机号
private String mobile;

//头像URL
private String avatarUrl;

//个人简介
private String bio;

//创建时间
private long ctime;

//更新时间
private long utime;

//状态(0:正常 1:冻结 2:注销等)
private int state;

//版本(用于乐观锁)
private int version;

public User(String username, String password) {
this.username = username;
this.password = password;
}
}
Loading

0 comments on commit 7d74352

Please sign in to comment.