diff --git a/lib/src/authentication/gate/gate.dart b/lib/src/authentication/gate/gate.dart new file mode 100644 index 0000000..b4eda9e --- /dev/null +++ b/lib/src/authentication/gate/gate.dart @@ -0,0 +1,40 @@ +class Gate { + static final Gate _instance = Gate._internal(); + + factory Gate() { + return _instance; + } + + Gate._internal(); + + /// All of the defined abilities. + final Map _abilities = {}; + + /// Define a new ability. + /// Gate().define('canDeletePost', () { + /// return user.id == post.user_id; + /// }); + void define(String ability, Function callback) { + _abilities[ability] = callback; + } + + /// Determine if all of the given abilities should be granted for the current user. + /// Gate().allows('canDeletePost'); + bool allows(String ability) { + final gate = _abilities[ability]; + if (gate != null) { + return gate(); + } + return false; + } + + /// Determine if a given ability has been defined. + bool has(String ability) { + return _abilities.containsKey(ability); + } + + /// Determine if any of the given abilities should be denied for the current user. + bool denies(String ability) { + return !allows(ability); + } +} diff --git a/lib/src/http/request/request.dart b/lib/src/http/request/request.dart index 12a3850..65f889d 100644 --- a/lib/src/http/request/request.dart +++ b/lib/src/http/request/request.dart @@ -12,6 +12,8 @@ class Request { Request.from({required this.request, this.route}); + Map? get user => Auth().user(); + String? get ip => request.connectionInfo?.remoteAddress.address; HttpHeaders get _httpHeaders => request.headers; diff --git a/lib/src/utils/helper.dart b/lib/src/utils/helper.dart index b6ffdc7..b1ebbd5 100644 --- a/lib/src/utils/helper.dart +++ b/lib/src/utils/helper.dart @@ -9,6 +9,10 @@ String url(String path) => '${env('APP_URL')}/$path'; String assets(String src) => url(src); +bool can(String ability) => Gate().allows(ability); + +bool cannot(String ability) => Gate().denies(ability); + T env(String key, [dynamic defaultValue]) => Env.get(key, defaultValue); abort(int code, String message) { diff --git a/lib/src/websocket/web_socket_handler.dart b/lib/src/websocket/web_socket_handler.dart index f6a2e5b..8deee63 100644 --- a/lib/src/websocket/web_socket_handler.dart +++ b/lib/src/websocket/web_socket_handler.dart @@ -53,6 +53,11 @@ class WebSocketHandler implements WebSocketEvent { }, })); + Function? openFunction = _events['${routePath}_connect']; + if (openFunction != null) { + Function.apply(openFunction, [client]); + } + websocket.listen((data) async { try { if (_middleware[_websocketRoute] != null) { @@ -107,8 +112,18 @@ class WebSocketHandler implements WebSocketEvent { } Function.apply(controller, [client, message]); }, onDone: () { + Function? openFunction = _events['${routePath}_disconnect']; + if (openFunction != null) { + Function.apply(openFunction, [client]); + } + _session.removeSession(sessionId); }, onError: (_) { + Function? openFunction = _events['${routePath}_error']; + if (openFunction != null) { + Function.apply(openFunction, [client]); + } + _session.removeSession(sessionId); }); } diff --git a/lib/vania.dart b/lib/vania.dart index 24a5fea..855ac54 100644 --- a/lib/vania.dart +++ b/lib/vania.dart @@ -63,3 +63,5 @@ export 'src/redis/vania_redis.dart'; export 'src/cache/redis_cache_driver.dart'; export 'src/http/validation/validation_chain/export_chain_validation.dart'; + +export 'src/authentication/gate/gate.dart';