11package  org .lowcoder .api .framework .plugin .endpoint ;
22
3+ import  static  org .lowcoder .sdk .exception .BizError .NOT_AUTHORIZED ;
34import  static  org .springframework .web .reactive .function .server .RequestPredicates .DELETE ;
45import  static  org .springframework .web .reactive .function .server .RequestPredicates .GET ;
56import  static  org .springframework .web .reactive .function .server .RequestPredicates .OPTIONS ;
89import  static  org .springframework .web .reactive .function .server .RequestPredicates .PUT ;
910import  static  org .springframework .web .reactive .function .server .RouterFunctions .route ;
1011
12+ import  java .lang .reflect .AccessibleObject ;
1113import  java .lang .reflect .InvocationTargetException ;
1214import  java .lang .reflect .Method ;
1315import  java .util .ArrayList ;
16+ import  java .util .Collections ;
1417import  java .util .List ;
1518
19+ import  org .aopalliance .intercept .MethodInvocation ;
1620import  org .apache .commons .collections4 .CollectionUtils ;
1721import  org .apache .commons .lang3 .StringUtils ;
22+ import  org .jetbrains .annotations .NotNull ;
23+ import  org .jetbrains .annotations .Nullable ;
1824import  org .lowcoder .api .framework .plugin .data .PluginServerRequest ;
25+ import  org .lowcoder .api .framework .plugin .security .PluginAuthorizationManager ;
1926import  org .lowcoder .api .framework .plugin .security .SecuredEndpoint ;
2027import  org .lowcoder .plugin .api .EndpointExtension ;
2128import  org .lowcoder .plugin .api .PluginEndpoint ;
2229import  org .lowcoder .plugin .api .data .EndpointRequest ;
2330import  org .lowcoder .plugin .api .data .EndpointResponse ;
2431import  org .lowcoder .sdk .exception .BaseException ;
32+ import  org .lowcoder .sdk .exception .BizException ;
2533import  org .springframework .aop .TargetSource ;
2634import  org .springframework .aop .framework .ProxyFactoryBean ;
35+ import  org .springframework .aop .framework .ReflectiveMethodInvocation ;
2736import  org .springframework .aop .target .SimpleBeanTargetSource ;
2837import  org .springframework .beans .factory .support .DefaultListableBeanFactory ;
2938import  org .springframework .context .ApplicationContext ;
3039import  org .springframework .context .support .GenericApplicationContext ;
3140import  org .springframework .core .ResolvableType ;
3241import  org .springframework .http .ResponseCookie ;
3342import  org .springframework .security .access .prepost .PreAuthorize ;
43+ import  org .springframework .security .authentication .UsernamePasswordAuthenticationToken ;
44+ import  org .springframework .security .authorization .AuthorizationDecision ;
45+ import  org .springframework .security .core .Authentication ;
3446import  org .springframework .security .core .context .ReactiveSecurityContextHolder ;
47+ import  org .springframework .security .core .context .SecurityContext ;
3548import  org .springframework .stereotype .Component ;
3649import  org .springframework .web .reactive .function .server .RequestPredicate ;
3750import  org .springframework .web .reactive .function .server .RouterFunction ;
@@ -52,6 +65,7 @@ public class PluginEndpointHandlerImpl implements PluginEndpointHandler
5265
5366	private  final  ApplicationContext  applicationContext ;
5467	private  final  DefaultListableBeanFactory  beanFactory ;
68+ 	private  final  PluginAuthorizationManager  pluginAuthorizationManager ;
5569
5670	@ Override 
5771	public  void  registerEndpoints (String  pluginUrlPrefix , List <PluginEndpoint > endpoints ) 
@@ -101,26 +115,69 @@ private void registerEndpointHandler(String urlPrefix, PluginEndpoint endpoint,
101115
102116		log .info ("Registered endpoint: {} -> {}: {}" , endpoint .getClass ().getSimpleName (), endpointMeta .method (), urlPrefix  + endpointMeta .uri ());
103117	}
104- 	
105- 	@ SecuredEndpoint 
118+ 
106119	public  Mono <ServerResponse > runPluginEndpointMethod (PluginEndpoint  endpoint , EndpointExtension  endpointMeta , Method  handler , ServerRequest  request )
107120	{
108- 		Mono <ServerResponse > result  = null ;
109- 		try 
110- 		{
111- 			log .info ("Running plugin endpoint method {}\n Request: {}" , handler .getName (), request );
121+ 		log .info ("Running plugin endpoint method {}\n Request: {}" , handler .getName (), request );
112122
113- 			EndpointResponse  response  = (EndpointResponse )handler .invoke (endpoint , PluginServerRequest .fromServerRequest (request ));
114- 			result  = createServerResponse (response );
115- 		}
116- 		catch  (IllegalAccessException  | InvocationTargetException  cause ) 
117- 		{
118- 			throw  new  BaseException ("Error running handler for [ "  + endpointMeta .method () + ": "  + endpointMeta .uri () + "] !" );
119- 		}
120- 		return  result ; 		
123+ 		Mono <Authentication > monoAuthentication  = ReactiveSecurityContextHolder .getContext ().map (SecurityContext ::getAuthentication ).cache ();
124+ 		Mono <AuthorizationDecision > decisionMono  = monoAuthentication .flatMap (authentication  -> {
125+ 			MethodInvocation  methodInvocation  = null ;
126+ 			try  {
127+ 				methodInvocation  = getMethodInvocation (endpointMeta , authentication );
128+ 			} catch  (NoSuchMethodException  e ) {
129+ 				return  Mono .error (new  RuntimeException (e ));
130+ 			}
131+ 			return  pluginAuthorizationManager .check (monoAuthentication , methodInvocation );
132+ 		});
133+ 
134+ 		return  decisionMono .<EndpointResponse >handle ((authorizationDecision , sink ) -> {
135+ 			if (!authorizationDecision .isGranted ()) sink .error (new  BizException (NOT_AUTHORIZED , "NOT_AUTHORIZED" ));
136+ 			try  {
137+ 				sink .next ((EndpointResponse ) handler .invoke (endpoint , PluginServerRequest .fromServerRequest (request )));
138+ 			} catch  (IllegalAccessException  | InvocationTargetException  e ) {
139+ 				sink .error (new  RuntimeException (e ));
140+ 			}
141+ 		}).flatMap (this ::createServerResponse );
121142	}
122- 	
123- 	
143+ 
144+ 	private  static  @ NotNull  MethodInvocation  getMethodInvocation (EndpointExtension  endpointMeta , Authentication  authentication ) throws  NoSuchMethodException  {
145+ 		Method  method  = Authentication .class .getMethod ("isAuthenticated" );
146+ 		Object [] arguments  = new  Object []{"someString" , endpointMeta };
147+         return  new  MethodInvocation () {
148+ 			@ NotNull 
149+ 			@ Override 
150+ 			public  Method  getMethod () {
151+ 				return  method ;
152+ 			}
153+ 
154+ 			@ NotNull 
155+ 			@ Override 
156+ 			public  Object [] getArguments () {
157+ 				return  arguments ;
158+ 			}
159+ 
160+ 			@ Nullable 
161+ 			@ Override 
162+ 			public  Object  proceed () throws  Throwable  {
163+ 				return  null ;
164+ 			}
165+ 
166+ 			@ Nullable 
167+ 			@ Override 
168+ 			public  Object  getThis () {
169+ 				return  authentication ;
170+ 			}
171+ 
172+ 			@ NotNull 
173+ 			@ Override 
174+ 			public  AccessibleObject  getStaticPart () {
175+ 				return  null ;
176+ 			}
177+ 		};
178+ 	}
179+ 
180+ 
124181	private  void  registerRouterFunctionMapping (String  endpointName , RouterFunction <ServerResponse > routerFunction )
125182	{
126183		String  beanName  = "pluginEndpoint_"  + endpointName  + "_"  + System .currentTimeMillis ();
0 commit comments