masonite-framework 5.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- masonite/__init__.py +1 -0
- masonite/api/Api.py +98 -0
- masonite/api/__init__.py +1 -0
- masonite/api/authentication/AuthenticatesTokens.py +16 -0
- masonite/api/authentication/__init__.py +1 -0
- masonite/api/commands/APIInstallCommand.py +55 -0
- masonite/api/controllers/AuthenticationController.py +27 -0
- masonite/api/controllers/__init__.py +1 -0
- masonite/api/facades/Api.py +5 -0
- masonite/api/facades/__init__.py +1 -0
- masonite/api/guards/JWTGuard.py +65 -0
- masonite/api/guards/__init__.py +1 -0
- masonite/api/middleware/JWTAuthenticationMiddleware.py +24 -0
- masonite/api/middleware/__init__.py +1 -0
- masonite/api/providers/ApiProvider.py +29 -0
- masonite/api/providers/__init__.py +1 -0
- masonite/api/stubs/api.py +15 -0
- masonite/api/stubs/routes/api.py +0 -0
- masonite/auth/MustVerifyEmail.py +26 -0
- masonite/auth/Sign.py +76 -0
- masonite/auth/__init__.py +2 -0
- masonite/authentication/Auth.py +195 -0
- masonite/authentication/__init__.py +2 -0
- masonite/authentication/guards/TestGuard.py +88 -0
- masonite/authentication/guards/WebGuard.py +86 -0
- masonite/authentication/guards/__init__.py +2 -0
- masonite/authentication/models/__init__.py +1 -0
- masonite/authentication/models/authenticates.py +76 -0
- masonite/authorization/AuthorizationResponse.py +30 -0
- masonite/authorization/AuthorizesRequest.py +9 -0
- masonite/authorization/Gate.py +170 -0
- masonite/authorization/Policy.py +9 -0
- masonite/authorization/__init__.py +5 -0
- masonite/authorization/models/__init__.py +1 -0
- masonite/authorization/models/authorizes.py +12 -0
- masonite/broadcasting/Broadcast.py +68 -0
- masonite/broadcasting/CanBroadcast.py +9 -0
- masonite/broadcasting/Channel.py +6 -0
- masonite/broadcasting/PresenceChannel.py +9 -0
- masonite/broadcasting/PrivateChannel.py +9 -0
- masonite/broadcasting/__init__.py +5 -0
- masonite/broadcasting/controllers/BroadcastingController.py +10 -0
- masonite/broadcasting/controllers/__init__.py +1 -0
- masonite/broadcasting/drivers/PusherDriver.py +37 -0
- masonite/broadcasting/drivers/__init__.py +1 -0
- masonite/broadcasting/providers/BroadcastProvider.py +20 -0
- masonite/broadcasting/providers/__init__.py +1 -0
- masonite/cache/Cache.py +56 -0
- masonite/cache/__init__.py +1 -0
- masonite/cache/drivers/FileDriver.py +109 -0
- masonite/cache/drivers/MemcachedDriver.py +92 -0
- masonite/cache/drivers/RedisDriver.py +185 -0
- masonite/cache/drivers/__init__.py +3 -0
- masonite/commands/AuthCommand.py +48 -0
- masonite/commands/Command.py +7 -0
- masonite/commands/CommandCapsule.py +36 -0
- masonite/commands/DownCommand.py +15 -0
- masonite/commands/Entry.py +24 -0
- masonite/commands/InstallCommand.py +51 -0
- masonite/commands/KeyCommand.py +33 -0
- masonite/commands/MakeCommandCommand.py +50 -0
- masonite/commands/MakeControllerCommand.py +89 -0
- masonite/commands/MakeJobCommand.py +48 -0
- masonite/commands/MakeMailableCommand.py +48 -0
- masonite/commands/MakeMiddlewareCommand.py +53 -0
- masonite/commands/MakePolicyCommand.py +68 -0
- masonite/commands/MakeProviderCommand.py +50 -0
- masonite/commands/MakeTestCommand.py +41 -0
- masonite/commands/MakeViewCommand.py +43 -0
- masonite/commands/PresetCommand.py +48 -0
- masonite/commands/ProjectCommand.py +271 -0
- masonite/commands/PublishPackageCommand.py +44 -0
- masonite/commands/QueueFailedCommand.py +33 -0
- masonite/commands/QueueRetryCommand.py +28 -0
- masonite/commands/QueueTableCommand.py +36 -0
- masonite/commands/QueueWorkCommand.py +31 -0
- masonite/commands/ServeCommand.py +73 -0
- masonite/commands/TinkerCommand.py +103 -0
- masonite/commands/UpCommand.py +15 -0
- masonite/commands/__init__.py +23 -0
- masonite/configuration/Configuration.py +80 -0
- masonite/configuration/__init__.py +2 -0
- masonite/configuration/helpers.py +5 -0
- masonite/configuration/providers/ConfigurationProvider.py +16 -0
- masonite/configuration/providers/__init__.py +1 -0
- masonite/container/__init__.py +1 -0
- masonite/container/container.py +494 -0
- masonite/controllers/Controller.py +5 -0
- masonite/controllers/RedirectController.py +10 -0
- masonite/controllers/ViewController.py +10 -0
- masonite/controllers/__init__.py +3 -0
- masonite/cookies/Cookie.py +47 -0
- masonite/cookies/CookieJar.py +83 -0
- masonite/cookies/__init__.py +2 -0
- masonite/cors/Cors.py +166 -0
- masonite/cors/__init__.py +1 -0
- masonite/drivers/BaseDriver.py +16 -0
- masonite/drivers/queue/AMQPDriver.py +185 -0
- masonite/drivers/queue/AsyncDriver.py +76 -0
- masonite/drivers/queue/DatabaseDriver.py +208 -0
- masonite/drivers/queue/__init__.py +3 -0
- masonite/drivers/session/CookieDriver.py +63 -0
- masonite/drivers/session/RedisDriver.py +157 -0
- masonite/drivers/session/__init__.py +2 -0
- masonite/dumps/Dump.py +90 -0
- masonite/dumps/Dumper.py +80 -0
- masonite/dumps/__init__.py +2 -0
- masonite/environment/__init__.py +1 -0
- masonite/environment/environment.py +74 -0
- masonite/events/Event.py +81 -0
- masonite/events/Listener.py +2 -0
- masonite/events/__init__.py +1 -0
- masonite/events/commands/MakeEventCommand.py +39 -0
- masonite/events/commands/MakeListenerCommand.py +38 -0
- masonite/events/commands/__init__.py +2 -0
- masonite/events/providers/EventProvider.py +18 -0
- masonite/events/providers/__init__.py +1 -0
- masonite/exceptions/DD.py +38 -0
- masonite/exceptions/ExceptionHandler.py +76 -0
- masonite/exceptions/__init__.py +38 -0
- masonite/exceptions/exceptionite/__init__.py +0 -0
- masonite/exceptions/exceptionite/blocks.py +101 -0
- masonite/exceptions/exceptionite/controllers.py +13 -0
- masonite/exceptions/exceptionite/solutions.py +66 -0
- masonite/exceptions/exceptionite/tabs.py +19 -0
- masonite/exceptions/exceptions.py +218 -0
- masonite/exceptions/handlers/DumpExceptionHandler.py +104 -0
- masonite/exceptions/handlers/HttpExceptionHandler.py +28 -0
- masonite/exceptions/handlers/ModelNotFoundHandler.py +13 -0
- masonite/facades/Auth.py +5 -0
- masonite/facades/Auth.pyi +32 -0
- masonite/facades/Broadcast.py +5 -0
- masonite/facades/Cache.py +5 -0
- masonite/facades/Config.py +5 -0
- masonite/facades/Config.pyi +14 -0
- masonite/facades/Dump.py +5 -0
- masonite/facades/Dump.pyi +26 -0
- masonite/facades/Facade.py +5 -0
- masonite/facades/Gate.py +5 -0
- masonite/facades/Gate.pyi +32 -0
- masonite/facades/Hash.py +5 -0
- masonite/facades/Hash.pyi +28 -0
- masonite/facades/Loader.py +5 -0
- masonite/facades/Loader.pyi +30 -0
- masonite/facades/Log.py +5 -0
- masonite/facades/Log.pyi +24 -0
- masonite/facades/Mail.py +5 -0
- masonite/facades/Mail.pyi +14 -0
- masonite/facades/Notification.py +5 -0
- masonite/facades/Notification.pyi +25 -0
- masonite/facades/Queue.py +5 -0
- masonite/facades/Queue.pyi +10 -0
- masonite/facades/RateLimiter.py +5 -0
- masonite/facades/RateLimiter.pyi +43 -0
- masonite/facades/Request.py +5 -0
- masonite/facades/Request.pyi +88 -0
- masonite/facades/Response.py +5 -0
- masonite/facades/Response.pyi +68 -0
- masonite/facades/Session.py +5 -0
- masonite/facades/Session.pyi +59 -0
- masonite/facades/Storage.py +5 -0
- masonite/facades/Storage.pyi +12 -0
- masonite/facades/Url.py +5 -0
- masonite/facades/Url.pyi +22 -0
- masonite/facades/View.py +5 -0
- masonite/facades/View.pyi +54 -0
- masonite/facades/__init__.py +20 -0
- masonite/filesystem/File.py +30 -0
- masonite/filesystem/FileStream.py +18 -0
- masonite/filesystem/Storage.py +38 -0
- masonite/filesystem/UploadedFile.py +36 -0
- masonite/filesystem/__init__.py +3 -0
- masonite/filesystem/drivers/AmazonS3Driver.py +163 -0
- masonite/filesystem/drivers/LocalDriver.py +123 -0
- masonite/filesystem/drivers/__init__.py +2 -0
- masonite/filesystem/providers/StorageProvider.py +20 -0
- masonite/filesystem/providers/__init__.py +1 -0
- masonite/foundation/Application.py +100 -0
- masonite/foundation/Kernel.py +100 -0
- masonite/foundation/__init__.py +3 -0
- masonite/foundation/response_handler.py +109 -0
- masonite/hashid/helpers/__init__.py +1 -0
- masonite/hashid/helpers/hashid.py +34 -0
- masonite/hashid/middleware/HashIDMiddleware.py +15 -0
- masonite/hashid/middleware/__init__.py +1 -0
- masonite/hashid/providers/HashIDProvider.py +13 -0
- masonite/hashing/Hash.py +56 -0
- masonite/hashing/__init__.py +1 -0
- masonite/hashing/drivers/Argon2Hasher.py +37 -0
- masonite/hashing/drivers/BcryptHasher.py +31 -0
- masonite/hashing/drivers/__init__.py +2 -0
- masonite/headers/Header.py +4 -0
- masonite/headers/HeaderBag.py +58 -0
- masonite/headers/__init__.py +2 -0
- masonite/helpers/__init__.py +5 -0
- masonite/helpers/compact.py +30 -0
- masonite/helpers/mix.py +34 -0
- masonite/helpers/optional.py +43 -0
- masonite/helpers/urls.py +69 -0
- masonite/input/Input.py +4 -0
- masonite/input/InputBag.py +231 -0
- masonite/input/__init__.py +1 -0
- masonite/loader/Loader.py +78 -0
- masonite/loader/__init__.py +1 -0
- masonite/logging/Logger.py +129 -0
- masonite/logging/LoggerExceptionsListener.py +26 -0
- masonite/logging/LoggerFactory.py +51 -0
- masonite/logging/LoggingProvider.py +34 -0
- masonite/logging/__init__.py +1 -0
- masonite/logging/drivers/BaseDriver.py +82 -0
- masonite/logging/drivers/DailyFileDriver.py +33 -0
- masonite/logging/drivers/SingleFileDriver.py +25 -0
- masonite/logging/drivers/SlackDriver.py +133 -0
- masonite/logging/drivers/StackDriver.py +12 -0
- masonite/logging/drivers/SysLogDriver.py +29 -0
- masonite/logging/drivers/TerminalDriver.py +52 -0
- masonite/logging/drivers/__init__.py +6 -0
- masonite/mail/Mail.py +37 -0
- masonite/mail/Mailable.py +108 -0
- masonite/mail/MessageAttachment.py +4 -0
- masonite/mail/MockMail.py +125 -0
- masonite/mail/Recipient.py +18 -0
- masonite/mail/__init__.py +3 -0
- masonite/mail/drivers/MailgunDriver.py +62 -0
- masonite/mail/drivers/SMTPDriver.py +80 -0
- masonite/mail/drivers/TerminalDriver.py +33 -0
- masonite/mail/drivers/__init__.py +3 -0
- masonite/middleware/__init__.py +15 -0
- masonite/middleware/middleware.py +2 -0
- masonite/middleware/middleware_capsule.py +73 -0
- masonite/middleware/route/ClearDumpsBetweenRequestsMiddleware.py +12 -0
- masonite/middleware/route/CorsMiddleware.py +49 -0
- masonite/middleware/route/EncryptCookies.py +27 -0
- masonite/middleware/route/GuardMiddleware.py +11 -0
- masonite/middleware/route/IpMiddleware.py +35 -0
- masonite/middleware/route/LoadUserMiddleware.py +11 -0
- masonite/middleware/route/MaintenanceModeMiddleware.py +16 -0
- masonite/middleware/route/SessionMiddleware.py +54 -0
- masonite/middleware/route/ShareErrorsInSessionMiddleware.py +19 -0
- masonite/middleware/route/ThrottleRequestsMiddleware.py +64 -0
- masonite/middleware/route/VerifyCsrfToken.py +69 -0
- masonite/middleware/route/__init__.py +1 -0
- masonite/notification/AnonymousNotifiable.py +39 -0
- masonite/notification/DatabaseNotification.py +38 -0
- masonite/notification/MockNotification.py +120 -0
- masonite/notification/Notifiable.py +68 -0
- masonite/notification/Notification.py +39 -0
- masonite/notification/NotificationManager.py +84 -0
- masonite/notification/SlackMessage.py +166 -0
- masonite/notification/Sms.py +54 -0
- masonite/notification/Textable.py +6 -0
- masonite/notification/__init__.py +9 -0
- masonite/notification/commands/MakeNotificationCommand.py +47 -0
- masonite/notification/commands/NotificationTableCommand.py +37 -0
- masonite/notification/commands/__init__.py +2 -0
- masonite/notification/drivers/BaseDriver.py +19 -0
- masonite/notification/drivers/BroadcastDriver.py +22 -0
- masonite/notification/drivers/DatabaseDriver.py +37 -0
- masonite/notification/drivers/MailDriver.py +21 -0
- masonite/notification/drivers/SlackDriver.py +110 -0
- masonite/notification/drivers/__init__.py +5 -0
- masonite/notification/drivers/vonage/VonageDriver.py +81 -0
- masonite/notification/providers/NotificationProvider.py +41 -0
- masonite/notification/providers/__init__.py +1 -0
- masonite/orm/commands/DbShellCommand.py +13 -0
- masonite/orm/commands/__init__.py +1 -0
- masonite/orm/providers/InternalORMProvider.py +48 -0
- masonite/orm/providers/__init__.py +1 -0
- masonite/packages/Package.py +68 -0
- masonite/packages/PublishableResource.py +14 -0
- masonite/packages/__init__.py +1 -0
- masonite/packages/providers/PackageProvider.py +200 -0
- masonite/packages/providers/__init__.py +1 -0
- masonite/packages/reserved_names.py +1 -0
- masonite/pipeline/Pipeline.py +13 -0
- masonite/pipeline/__init__.py +1 -0
- masonite/pipeline/tasks/MiddlewareTask.py +0 -0
- masonite/pipeline/tasks/ResponseTask.py +7 -0
- masonite/presets/Bootstrap.py +38 -0
- masonite/presets/Preset.py +75 -0
- masonite/presets/PresetsCapsule.py +16 -0
- masonite/presets/React.py +60 -0
- masonite/presets/Remove.py +50 -0
- masonite/presets/Tailwind.py +37 -0
- masonite/presets/Vue.py +51 -0
- masonite/presets/__init__.py +6 -0
- masonite/presets/providers/PresetsProvider.py +25 -0
- masonite/presets/providers/__init__.py +1 -0
- masonite/providers/AuthenticationProvider.py +18 -0
- masonite/providers/AuthorizationProvider.py +13 -0
- masonite/providers/CacheProvider.py +19 -0
- masonite/providers/ExceptionProvider.py +86 -0
- masonite/providers/FrameworkProvider.py +53 -0
- masonite/providers/HashServiceProvider.py +20 -0
- masonite/providers/HelpersProvider.py +38 -0
- masonite/providers/MailProvider.py +25 -0
- masonite/providers/Provider.py +15 -0
- masonite/providers/QueueProvider.py +18 -0
- masonite/providers/RouteProvider.py +73 -0
- masonite/providers/SessionProvider.py +20 -0
- masonite/providers/ViewProvider.py +35 -0
- masonite/providers/WhitenoiseProvider.py +26 -0
- masonite/providers/__init__.py +24 -0
- masonite/queues/Queue.py +45 -0
- masonite/queues/Queueable.py +25 -0
- masonite/queues/ShouldQueue.py +2 -0
- masonite/queues/__init__.py +3 -0
- masonite/rates/Limit.py +39 -0
- masonite/rates/RateLimiter.py +91 -0
- masonite/rates/__init__.py +3 -0
- masonite/rates/limiters.py +41 -0
- masonite/rates/providers/RateProvider.py +14 -0
- masonite/rates/providers/__init__.py +1 -0
- masonite/request/__init__.py +1 -0
- masonite/request/request.py +184 -0
- masonite/request/validation.py +14 -0
- masonite/response/__init__.py +1 -0
- masonite/response/response.py +252 -0
- masonite/routes/HTTPRoute.py +399 -0
- masonite/routes/Route.py +242 -0
- masonite/routes/Router.py +136 -0
- masonite/routes/__init__.py +3 -0
- masonite/routes/commands/RouteListCommand.py +67 -0
- masonite/routes/commands/__init__.py +1 -0
- masonite/scheduling/CanSchedule.py +10 -0
- masonite/scheduling/CommandTask.py +13 -0
- masonite/scheduling/Task.py +148 -0
- masonite/scheduling/TaskHandler.py +30 -0
- masonite/scheduling/__init__.py +4 -0
- masonite/scheduling/commands/MakeTaskCommand.py +47 -0
- masonite/scheduling/commands/ScheduleRunCommand.py +20 -0
- masonite/scheduling/commands/__init__.py +2 -0
- masonite/scheduling/providers/ScheduleProvider.py +20 -0
- masonite/scheduling/providers/__init__.py +1 -0
- masonite/sessions/Session.py +180 -0
- masonite/sessions/__init__.py +2 -0
- masonite/sessions/helpers.py +6 -0
- masonite/storage/__init__.py +1 -0
- masonite/storage/storage.py +10 -0
- masonite/stubs/auth/mailables/ResetPassword.py +15 -0
- masonite/stubs/commands/Command.py +20 -0
- masonite/stubs/controllers/APIController.py +19 -0
- masonite/stubs/controllers/Controller.py +7 -0
- masonite/stubs/controllers/ResourceController.py +25 -0
- masonite/stubs/controllers/auth/HomeController.py +7 -0
- masonite/stubs/controllers/auth/LoginController.py +25 -0
- masonite/stubs/controllers/auth/PasswordResetController.py +40 -0
- masonite/stubs/controllers/auth/RegisterController.py +31 -0
- masonite/stubs/events/Event.py +2 -0
- masonite/stubs/events/Listener.py +3 -0
- masonite/stubs/jobs/Job.py +6 -0
- masonite/stubs/mailable/Mailable.py +12 -0
- masonite/stubs/middlewares/Middleware.py +9 -0
- masonite/stubs/notification/Notification.py +15 -0
- masonite/stubs/notification/create_notifications_table.py +17 -0
- masonite/stubs/policies/ModelPolicy.py +24 -0
- masonite/stubs/policies/Policy.py +6 -0
- masonite/stubs/presets/base/app.css +1 -0
- masonite/stubs/presets/base/app.js +2 -0
- masonite/stubs/presets/base/bootstrap.js +23 -0
- masonite/stubs/presets/base/package.json +17 -0
- masonite/stubs/presets/base/webpack.mix.js +23 -0
- masonite/stubs/presets/bootstrap/_variables.scss +19 -0
- masonite/stubs/presets/bootstrap/app.scss +13 -0
- masonite/stubs/presets/bootstrap/webpack.mix.js +21 -0
- masonite/stubs/presets/react/Example.js +22 -0
- masonite/stubs/presets/react/app.html +21 -0
- masonite/stubs/presets/react/app.js +15 -0
- masonite/stubs/presets/react/webpack.mix.js +22 -0
- masonite/stubs/presets/tailwind/app.css +3 -0
- masonite/stubs/presets/tailwind/tailwind.config.js +11 -0
- masonite/stubs/presets/tailwind/webpack.mix.js +23 -0
- masonite/stubs/presets/vue/App.vue +26 -0
- masonite/stubs/presets/vue/HelloWorld.vue +35 -0
- masonite/stubs/presets/vue/app.html +21 -0
- masonite/stubs/presets/vue/app.js +46 -0
- masonite/stubs/presets/vue/webpack.mix.js +22 -0
- masonite/stubs/providers/Provider.py +12 -0
- masonite/stubs/queue/create_failed_jobs_table.py +20 -0
- masonite/stubs/queue/create_queue_jobs_table.py +20 -0
- masonite/stubs/scheduling/Task.py +7 -0
- masonite/stubs/templates/auth/base.html +13 -0
- masonite/stubs/templates/auth/change_password.html +77 -0
- masonite/stubs/templates/auth/home.html +17 -0
- masonite/stubs/templates/auth/login.html +78 -0
- masonite/stubs/templates/auth/mailables/reset_password.html +31 -0
- masonite/stubs/templates/auth/password_reset.html +68 -0
- masonite/stubs/templates/auth/register.html +85 -0
- masonite/stubs/templates/view.html +16 -0
- masonite/stubs/tests/TestCase.py +9 -0
- masonite/stubs/validation/Rule.py +48 -0
- masonite/stubs/validation/RuleEnclosure.py +18 -0
- masonite/templates/__init__.py +0 -0
- masonite/templates/assets/github-dark.min.css +10 -0
- masonite/templates/assets/highlight.min.js +384 -0
- masonite/templates/assets/tailwind.css +1 -0
- masonite/templates/dump.html +93 -0
- masonite/tests/DatabaseTransactions.py +8 -0
- masonite/tests/HttpTestResponse.py +374 -0
- masonite/tests/MockInput.py +6 -0
- masonite/tests/TestCase.py +493 -0
- masonite/tests/TestCommand.py +65 -0
- masonite/tests/TestResponseCapsule.py +17 -0
- masonite/tests/__init__.py +4 -0
- masonite/utils/__init__.py +0 -0
- masonite/utils/collections.py +545 -0
- masonite/utils/console.py +39 -0
- masonite/utils/data/mime.types +1863 -0
- masonite/utils/filesystem.py +100 -0
- masonite/utils/http.py +101 -0
- masonite/utils/location.py +90 -0
- masonite/utils/str.py +120 -0
- masonite/utils/structures.py +127 -0
- masonite/utils/time.py +58 -0
- masonite/validation/MessageBag.py +123 -0
- masonite/validation/RuleEnclosure.py +2 -0
- masonite/validation/Validator.py +1578 -0
- masonite/validation/__init__.py +52 -0
- masonite/validation/commands/MakeRuleCommand.py +48 -0
- masonite/validation/commands/MakeRuleEnclosureCommand.py +49 -0
- masonite/validation/commands/__init__.py +0 -0
- masonite/validation/decorators.py +20 -0
- masonite/validation/providers/ValidationProvider.py +23 -0
- masonite/validation/providers/__init__.py +1 -0
- masonite/validation/resources/postal_codes.py +1011 -0
- masonite/views/ViewCapsule.py +0 -0
- masonite/views/__init__.py +1 -0
- masonite/views/view.py +255 -0
- masonite_framework-5.0.0.dist-info/METADATA +146 -0
- masonite_framework-5.0.0.dist-info/RECORD +434 -0
- masonite_framework-5.0.0.dist-info/WHEEL +5 -0
- masonite_framework-5.0.0.dist-info/entry_points.txt +2 -0
- masonite_framework-5.0.0.dist-info/licenses/LICENSE +21 -0
- masonite_framework-5.0.0.dist-info/top_level.txt +1 -0
masonite/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "5.0.0"
|
masonite/api/Api.py
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import jwt
|
|
2
|
+
import pendulum
|
|
3
|
+
from ..routes import Route
|
|
4
|
+
from .controllers import AuthenticationController
|
|
5
|
+
from ..utils.str import random_string
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Api:
|
|
9
|
+
def __init__(self, application, driver_config=None):
|
|
10
|
+
self.application = application
|
|
11
|
+
|
|
12
|
+
def set_configuration(self, config):
|
|
13
|
+
self.config = config
|
|
14
|
+
return self
|
|
15
|
+
|
|
16
|
+
def generate_token(self):
|
|
17
|
+
secret = self.config.get("jwt").get("secret")
|
|
18
|
+
algorithm = self.config.get("jwt").get("algorithm")
|
|
19
|
+
expire_minutes = self.config.get("jwt").get("expires")
|
|
20
|
+
version = self.config.get("jwt").get("version")
|
|
21
|
+
if expire_minutes:
|
|
22
|
+
expire_minutes = (
|
|
23
|
+
pendulum.now(tz="UTC").add(minutes=expire_minutes).to_datetime_string()
|
|
24
|
+
)
|
|
25
|
+
token = jwt.encode(
|
|
26
|
+
{"expires": expire_minutes, "version": version, "random": random_string(10)}, secret, algorithm=algorithm
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
return token
|
|
30
|
+
|
|
31
|
+
def get_token(self):
|
|
32
|
+
request = self.application.make("request")
|
|
33
|
+
token = request.input("token")
|
|
34
|
+
|
|
35
|
+
if token:
|
|
36
|
+
return token
|
|
37
|
+
|
|
38
|
+
header = request.header("Authorization")
|
|
39
|
+
|
|
40
|
+
if header:
|
|
41
|
+
return header.replace("Bearer ", "")
|
|
42
|
+
|
|
43
|
+
def validate_token(self, token):
|
|
44
|
+
secret = self.config.get("jwt").get("secret")
|
|
45
|
+
algorithm = self.config.get("jwt").get("algorithm")
|
|
46
|
+
expire_minutes = self.config.get("jwt").get("expires")
|
|
47
|
+
authenticates = self.config.get("jwt").get("authenticates")
|
|
48
|
+
version = self.config.get("jwt").get("version")
|
|
49
|
+
if expire_minutes:
|
|
50
|
+
expire_minutes = (
|
|
51
|
+
pendulum.now(tz="UTC").add(minutes=expire_minutes).to_datetime_string()
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
try:
|
|
55
|
+
unencrypted_token = jwt.decode(token, secret, algorithms=[algorithm])
|
|
56
|
+
except (jwt.InvalidSignatureError, jwt.DecodeError):
|
|
57
|
+
return False
|
|
58
|
+
expires = unencrypted_token.get("expires")
|
|
59
|
+
|
|
60
|
+
if version:
|
|
61
|
+
if unencrypted_token["version"] != version:
|
|
62
|
+
return False
|
|
63
|
+
|
|
64
|
+
if authenticates:
|
|
65
|
+
return self.attempt_by_token(token)
|
|
66
|
+
|
|
67
|
+
if not expires:
|
|
68
|
+
return True
|
|
69
|
+
|
|
70
|
+
expired = pendulum.parse(expires, tz="UTC").is_past()
|
|
71
|
+
|
|
72
|
+
if expired:
|
|
73
|
+
return False
|
|
74
|
+
|
|
75
|
+
return True
|
|
76
|
+
|
|
77
|
+
def regenerate_token(self, token):
|
|
78
|
+
# if the token can be decoded, regenerate new token
|
|
79
|
+
secret = self.config.get("jwt").get("secret")
|
|
80
|
+
algorithm = self.config.get("jwt").get("algorithm")
|
|
81
|
+
try:
|
|
82
|
+
jwt.decode(token, secret, algorithms=[algorithm])
|
|
83
|
+
return self.generate_token()
|
|
84
|
+
except jwt.DecodeError:
|
|
85
|
+
pass
|
|
86
|
+
|
|
87
|
+
return False
|
|
88
|
+
|
|
89
|
+
def attempt_by_token(self, token):
|
|
90
|
+
model = self.config.get("jwt").get("model")()
|
|
91
|
+
return model.attempt_by_token(token)
|
|
92
|
+
|
|
93
|
+
@classmethod
|
|
94
|
+
def routes(cls, auth_route="/api/auth", reauth_route="/api/reauth"):
|
|
95
|
+
return [
|
|
96
|
+
Route.post("/api/auth", AuthenticationController.auth),
|
|
97
|
+
Route.post("/api/reauth", AuthenticationController.reauth),
|
|
98
|
+
]
|
masonite/api/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .Api import Api
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from ..facades import Api
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class AuthenticatesTokens:
|
|
5
|
+
|
|
6
|
+
__TOKEN_COLUMN__ = "api_token"
|
|
7
|
+
|
|
8
|
+
def generate_jwt(self):
|
|
9
|
+
token = Api.generate_token()
|
|
10
|
+
|
|
11
|
+
setattr(self, self.__TOKEN_COLUMN__, token)
|
|
12
|
+
self.save()
|
|
13
|
+
return token
|
|
14
|
+
|
|
15
|
+
def attempt_by_token(self, token):
|
|
16
|
+
return self.where(self.__TOKEN_COLUMN__, token).first()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .AuthenticatesTokens import AuthenticatesTokens
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""Scaffold Auth Command."""
|
|
2
|
+
import os
|
|
3
|
+
from ...utils.filesystem import render_stub_file, get_module_dir
|
|
4
|
+
from ...utils.location import config_path
|
|
5
|
+
from ...utils.str import random_string
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
from ...commands.Command import Command
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class APIInstallCommand(Command):
|
|
12
|
+
"""
|
|
13
|
+
Adds required files for building API's
|
|
14
|
+
|
|
15
|
+
api:install
|
|
16
|
+
{--f|force=? : Force overriding file if already exists}
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, application):
|
|
20
|
+
super().__init__()
|
|
21
|
+
self.app = application
|
|
22
|
+
|
|
23
|
+
def handle(self):
|
|
24
|
+
stub_path = self.get_stub_config_path()
|
|
25
|
+
|
|
26
|
+
content = render_stub_file(stub_path, "api.py")
|
|
27
|
+
|
|
28
|
+
path = config_path("api.py")
|
|
29
|
+
if os.path.exists(path) and not self.option("force"):
|
|
30
|
+
self.warning(
|
|
31
|
+
f"{path} already exists! Run the command with -f (force) to override."
|
|
32
|
+
)
|
|
33
|
+
return -1
|
|
34
|
+
|
|
35
|
+
with open(path, "w") as f:
|
|
36
|
+
f.write(content)
|
|
37
|
+
|
|
38
|
+
if os.path.exists(path) and not self.option("force"):
|
|
39
|
+
self.warning(
|
|
40
|
+
f"{path} already exists! Run the command with -f (force) to override."
|
|
41
|
+
)
|
|
42
|
+
return -1
|
|
43
|
+
|
|
44
|
+
with open(path, "w") as f:
|
|
45
|
+
f.write(content)
|
|
46
|
+
|
|
47
|
+
secret = random_string(25)
|
|
48
|
+
|
|
49
|
+
self.info(f"API Installed: ({config_path('api.py', absolute=False)})")
|
|
50
|
+
self.info(
|
|
51
|
+
f"JWT Secret Key Is: {secret}. You should store this in an environment variable called JWT_SECRET."
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
def get_stub_config_path(self):
|
|
55
|
+
return os.path.join(get_module_dir(__file__), "../stubs/api.py")
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from ...controllers import Controller
|
|
2
|
+
from ...request import Request
|
|
3
|
+
from ...response import Response
|
|
4
|
+
from ...authentication import Auth
|
|
5
|
+
from ..facades import Api
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AuthenticationController(Controller):
|
|
9
|
+
def auth(self, auth: Auth, request: Request, response: Response):
|
|
10
|
+
user = auth.attempt(request.input("username"), request.input("password"))
|
|
11
|
+
|
|
12
|
+
if user:
|
|
13
|
+
return {"data": user.generate_jwt()}
|
|
14
|
+
|
|
15
|
+
return response.json(
|
|
16
|
+
{"message": "Could not find username or password"}, status="403"
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
def reauth(self, request: Request, response: Response):
|
|
20
|
+
user = Api.attempt_by_token(request.input("token"))
|
|
21
|
+
|
|
22
|
+
if user:
|
|
23
|
+
return {"data": user.generate_jwt()}
|
|
24
|
+
|
|
25
|
+
return response.json(
|
|
26
|
+
{"message": "Could not reauthenticate based on given token."}, status="403"
|
|
27
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .AuthenticationController import AuthenticationController
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .Api import Api
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from ..facades import Api
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class JWTGuard:
|
|
5
|
+
def __init__(self, application):
|
|
6
|
+
self.application = application
|
|
7
|
+
self.connection = None
|
|
8
|
+
|
|
9
|
+
def set_options(self, options):
|
|
10
|
+
self.options = options
|
|
11
|
+
return self
|
|
12
|
+
|
|
13
|
+
def attempt(self, username, password):
|
|
14
|
+
attempt = self.options.get("model")().attempt(username, password)
|
|
15
|
+
if attempt:
|
|
16
|
+
return attempt
|
|
17
|
+
|
|
18
|
+
def get_auth_column(self, username):
|
|
19
|
+
return self.options.get("model")().get_auth_column(username)
|
|
20
|
+
|
|
21
|
+
def register(self, dictionary):
|
|
22
|
+
try:
|
|
23
|
+
register = self.options.get("model")().register(dictionary)
|
|
24
|
+
except Exception:
|
|
25
|
+
return False
|
|
26
|
+
return self.attempt_by_id(register.get_id())
|
|
27
|
+
|
|
28
|
+
def user(self):
|
|
29
|
+
"""Get the currently logged in user.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
object|bool -- Returns the current authenticated user object or False or None if there is none.
|
|
33
|
+
"""
|
|
34
|
+
# token = self.application.make("request").cookie("token")
|
|
35
|
+
token = Api.get_token()
|
|
36
|
+
if token and self.options.get("model")():
|
|
37
|
+
return self.options.get("model")().attempt_by_token(token) or False
|
|
38
|
+
|
|
39
|
+
return False
|
|
40
|
+
|
|
41
|
+
def attempt_by_id(self, user_id):
|
|
42
|
+
"""Login a user by the user ID.
|
|
43
|
+
|
|
44
|
+
Arguments:
|
|
45
|
+
user_id {string|int} -- The ID of the user model record.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
object|False -- Returns the current authenticated user object or False or None if there is none.
|
|
49
|
+
"""
|
|
50
|
+
attempt = self.options.get("model")().attempt_by_id(user_id)
|
|
51
|
+
|
|
52
|
+
if attempt and not self.options.get("once"):
|
|
53
|
+
self.application.make("request").set_user(attempt)
|
|
54
|
+
return attempt
|
|
55
|
+
|
|
56
|
+
return False
|
|
57
|
+
|
|
58
|
+
def once(self):
|
|
59
|
+
"""Log in the user without saving a cookie.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
self
|
|
63
|
+
"""
|
|
64
|
+
self._once = True
|
|
65
|
+
return self
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .JWTGuard import JWTGuard
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from masonite.middleware import Middleware
|
|
2
|
+
|
|
3
|
+
from masonite.api.facades import Api
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class JWTAuthenticationMiddleware(Middleware):
|
|
7
|
+
def before(self, request, response):
|
|
8
|
+
token = Api.get_token()
|
|
9
|
+
if not token:
|
|
10
|
+
return response.json(
|
|
11
|
+
{"message": "Authentication token missing"}, status="401"
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
# Check token is not expired
|
|
15
|
+
validate = Api.validate_token(token)
|
|
16
|
+
if not validate:
|
|
17
|
+
return response.json(
|
|
18
|
+
{"message": "Token invalid. Try reauthenticating."}, status=401
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
return request
|
|
22
|
+
|
|
23
|
+
def after(self, request, response):
|
|
24
|
+
pass
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .JWTAuthenticationMiddleware import JWTAuthenticationMiddleware
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from ..guards import JWTGuard
|
|
2
|
+
from ..commands.APIInstallCommand import APIInstallCommand
|
|
3
|
+
from ...configuration.helpers import config
|
|
4
|
+
from ...providers import Provider
|
|
5
|
+
from ..Api import Api
|
|
6
|
+
|
|
7
|
+
from ...routes import Route
|
|
8
|
+
from ...utils.structures import load
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ApiProvider(Provider):
|
|
12
|
+
def __init__(self, application):
|
|
13
|
+
self.application = application
|
|
14
|
+
|
|
15
|
+
def register(self):
|
|
16
|
+
api = Api(self.application).set_configuration(config("api.drivers"))
|
|
17
|
+
self.application.bind("api", api)
|
|
18
|
+
self.application.make("router").add(
|
|
19
|
+
Route.group(
|
|
20
|
+
load(self.application.make("routes.api.location"), "ROUTES"),
|
|
21
|
+
middleware=["api"],
|
|
22
|
+
prefix="/api",
|
|
23
|
+
)
|
|
24
|
+
)
|
|
25
|
+
self.application.make("commands").add(APIInstallCommand(self.application))
|
|
26
|
+
self.application.make("auth").add_guard("jwt", JWTGuard(self.application))
|
|
27
|
+
|
|
28
|
+
def boot(self):
|
|
29
|
+
pass
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .ApiProvider import ApiProvider
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"""API Config"""
|
|
2
|
+
from masonite.environment import env
|
|
3
|
+
|
|
4
|
+
from app.models.User import User
|
|
5
|
+
|
|
6
|
+
DRIVERS = {
|
|
7
|
+
"jwt": {
|
|
8
|
+
"algorithm": "HS512",
|
|
9
|
+
"secret": env("JWT_SECRET"),
|
|
10
|
+
"model": User,
|
|
11
|
+
"expires": None,
|
|
12
|
+
"authenticates": False,
|
|
13
|
+
"version": None,
|
|
14
|
+
}
|
|
15
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Verify Email Module."""
|
|
2
|
+
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
from ..auth.Sign import Sign
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class MustVerifyEmail:
|
|
9
|
+
"""Class To Verify User Email."""
|
|
10
|
+
|
|
11
|
+
def verify_email(self, mail_manager, request):
|
|
12
|
+
"""Sends email for user verification
|
|
13
|
+
|
|
14
|
+
Arguments:
|
|
15
|
+
mail_manager {masonite.managers.MailManager} -- Masonite mail manager class.
|
|
16
|
+
request {masonite.request.Request} -- Masonite request class.
|
|
17
|
+
"""
|
|
18
|
+
mail = mail_manager.helper()
|
|
19
|
+
sign = Sign()
|
|
20
|
+
|
|
21
|
+
token = sign.sign("{0}::{1}".format(self.id, time.time()))
|
|
22
|
+
link = "{0}/email/verify/{1}".format(request.environ["HTTP_HOST"], token)
|
|
23
|
+
|
|
24
|
+
mail.to(self.email).template(
|
|
25
|
+
"auth/verifymail", {"name": self.name, "email": self.email, "link": link}
|
|
26
|
+
).subject("Please Confirm Your Email").send()
|
masonite/auth/Sign.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Cryptographic Signing Module."""
|
|
2
|
+
import binascii
|
|
3
|
+
|
|
4
|
+
from cryptography.fernet import Fernet, InvalidToken as CryptographyInvalidToken
|
|
5
|
+
|
|
6
|
+
from ..exceptions import InvalidSecretKey, InvalidToken
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Sign:
|
|
10
|
+
"""Cryptographic signing class."""
|
|
11
|
+
|
|
12
|
+
def __init__(self, key=None):
|
|
13
|
+
"""Sign constructor.
|
|
14
|
+
|
|
15
|
+
Keyword Arguments:
|
|
16
|
+
key {string} -- The secret key to use. If nothing is passed it then it will use
|
|
17
|
+
the secret key from the config file. (default: {None})
|
|
18
|
+
|
|
19
|
+
Raises:
|
|
20
|
+
InvalidSecretKey -- Thrown if the secret key does not exist.
|
|
21
|
+
"""
|
|
22
|
+
if key:
|
|
23
|
+
self.key = key
|
|
24
|
+
else:
|
|
25
|
+
from wsgi import application
|
|
26
|
+
|
|
27
|
+
self.key = application.make("key")
|
|
28
|
+
|
|
29
|
+
if not self.key:
|
|
30
|
+
raise InvalidSecretKey(
|
|
31
|
+
"The encryption key passed in is: None. Be sure there is a secret key present in your .env file or your config/application.py file."
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
self.encryption = None
|
|
35
|
+
|
|
36
|
+
def sign(self, value):
|
|
37
|
+
"""Sign a value using the secret key.
|
|
38
|
+
|
|
39
|
+
Arguments:
|
|
40
|
+
value {string} -- The value to be encrypted.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
string -- Returns the encrypted value.
|
|
44
|
+
|
|
45
|
+
Raises:
|
|
46
|
+
InvalidSecretKey -- Thrown if the secret key has incorrect padding.
|
|
47
|
+
"""
|
|
48
|
+
try:
|
|
49
|
+
f = Fernet(self.key)
|
|
50
|
+
except (binascii.Error, ValueError):
|
|
51
|
+
raise InvalidSecretKey(
|
|
52
|
+
"You have passed an invalid secret key of: {}. Make sure you have correctly added your secret key.".format(
|
|
53
|
+
self.key
|
|
54
|
+
)
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
self.encryption = f.encrypt(bytes(str(value), "utf-8"))
|
|
58
|
+
return self.encryption.decode("utf-8")
|
|
59
|
+
|
|
60
|
+
def unsign(self, value=None):
|
|
61
|
+
"""Unsign the value using the secret key.
|
|
62
|
+
|
|
63
|
+
Keyword Arguments:
|
|
64
|
+
value {string} -- The value to be unencrypted. (default: {None})
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
string -- Returns the unencrypted value.
|
|
68
|
+
"""
|
|
69
|
+
f = Fernet(self.key)
|
|
70
|
+
|
|
71
|
+
if not value:
|
|
72
|
+
return f.decrypt(self.encryption).decode("utf-8")
|
|
73
|
+
try:
|
|
74
|
+
return f.decrypt(bytes(str(value), "utf-8")).decode("utf-8")
|
|
75
|
+
except CryptographyInvalidToken as e:
|
|
76
|
+
raise InvalidToken("Invalid Cryptographic Token") from e
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import pendulum
|
|
2
|
+
import uuid
|
|
3
|
+
from ..routes import Route
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Auth:
|
|
7
|
+
def __init__(self, application, guard_config=None):
|
|
8
|
+
self.application = application
|
|
9
|
+
self.guards = {}
|
|
10
|
+
self._guard = None
|
|
11
|
+
self.guard_config = guard_config or {}
|
|
12
|
+
self.options = {}
|
|
13
|
+
|
|
14
|
+
self._user = None
|
|
15
|
+
|
|
16
|
+
def add_guard(self, name, guard):
|
|
17
|
+
self.guards.update({name: guard})
|
|
18
|
+
|
|
19
|
+
def set_configuration(self, config):
|
|
20
|
+
self.guard_config = config
|
|
21
|
+
return self
|
|
22
|
+
|
|
23
|
+
def guard(self, guard):
|
|
24
|
+
self._guard = guard
|
|
25
|
+
return self
|
|
26
|
+
|
|
27
|
+
def get_guard(self, name=None):
|
|
28
|
+
if name is None and self._guard is None:
|
|
29
|
+
return self.guards[self.guard_config.get("default")]
|
|
30
|
+
|
|
31
|
+
return self.guards[self._guard]
|
|
32
|
+
|
|
33
|
+
def get_config_options(self, guard=None):
|
|
34
|
+
if guard is None:
|
|
35
|
+
options = self.guard_config.get(self.guard_config.get("default"), {})
|
|
36
|
+
options.update(self.options)
|
|
37
|
+
return options
|
|
38
|
+
|
|
39
|
+
options = self.guard_config.get(guard, {})
|
|
40
|
+
options.update(self.options)
|
|
41
|
+
return options
|
|
42
|
+
|
|
43
|
+
def attempt(self, email, password, once=False):
|
|
44
|
+
auth_config = self.get_config_options()
|
|
45
|
+
auth_config.update({"once": once})
|
|
46
|
+
user = self.get_guard().set_options(auth_config).attempt(email, password)
|
|
47
|
+
self.set_user(user)
|
|
48
|
+
return user
|
|
49
|
+
|
|
50
|
+
def attempt_by_id(self, user_id, once=False):
|
|
51
|
+
auth_config = self.get_config_options()
|
|
52
|
+
auth_config.update({"once": once})
|
|
53
|
+
user = self.get_guard().set_options(auth_config).attempt_by_id(user_id)
|
|
54
|
+
self.set_user(user)
|
|
55
|
+
return user
|
|
56
|
+
|
|
57
|
+
def logout(self):
|
|
58
|
+
"""Logout the current authenticated user.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
self
|
|
62
|
+
"""
|
|
63
|
+
self.application.make("request").remove_user()
|
|
64
|
+
self.application.make("response").delete_cookie("token")
|
|
65
|
+
self.get_guard().set_options(self.get_config_options()).logout()
|
|
66
|
+
self._user = None
|
|
67
|
+
|
|
68
|
+
def user(self):
|
|
69
|
+
"""Get the current authenticated user.
|
|
70
|
+
|
|
71
|
+
Returns:
|
|
72
|
+
self
|
|
73
|
+
"""
|
|
74
|
+
if self._user:
|
|
75
|
+
return self._user
|
|
76
|
+
return self.get_guard().set_options(self.get_config_options()).user()
|
|
77
|
+
|
|
78
|
+
def register(self, dictionary):
|
|
79
|
+
"""Logout the current authenticated user.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
self
|
|
83
|
+
"""
|
|
84
|
+
auth_config = self.get_config_options()
|
|
85
|
+
return self.get_guard().set_options(auth_config).register(dictionary)
|
|
86
|
+
|
|
87
|
+
def set_user(self, user):
|
|
88
|
+
self._user = user
|
|
89
|
+
return self
|
|
90
|
+
|
|
91
|
+
def password_reset(self, email):
|
|
92
|
+
"""Logout the current authenticated user.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
self
|
|
96
|
+
"""
|
|
97
|
+
token = str(uuid.uuid4())
|
|
98
|
+
auth_config = self.get_config_options()
|
|
99
|
+
auth = self.get_guard().set_options(auth_config).get_auth_column(email)
|
|
100
|
+
if not auth:
|
|
101
|
+
return (None, None)
|
|
102
|
+
try:
|
|
103
|
+
existing = (
|
|
104
|
+
self.application.make("builder")
|
|
105
|
+
.new()
|
|
106
|
+
.table(self.guard_config.get("password_reset_table"))
|
|
107
|
+
.where("email", email)
|
|
108
|
+
.first()
|
|
109
|
+
)
|
|
110
|
+
if existing:
|
|
111
|
+
token = existing["token"]
|
|
112
|
+
else:
|
|
113
|
+
self.application.make("builder").new().table(
|
|
114
|
+
self.guard_config.get("password_reset_table")
|
|
115
|
+
).create(
|
|
116
|
+
{
|
|
117
|
+
"email": email,
|
|
118
|
+
"token": token,
|
|
119
|
+
"expires_at": pendulum.now()
|
|
120
|
+
.add(minutes=self.guard_config.get("password_reset_expiration"))
|
|
121
|
+
.to_datetime_string()
|
|
122
|
+
if self.guard_config.get("password_reset_expiration")
|
|
123
|
+
else None,
|
|
124
|
+
"created_at": pendulum.now().to_datetime_string(),
|
|
125
|
+
}
|
|
126
|
+
)
|
|
127
|
+
except Exception:
|
|
128
|
+
return (None, None)
|
|
129
|
+
|
|
130
|
+
self.application.make("event").fire("auth.password_reset", email, token)
|
|
131
|
+
return auth, token
|
|
132
|
+
|
|
133
|
+
def reset_password(self, password, token):
|
|
134
|
+
"""Logout the current authenticated user.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
self
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
reset_record = (
|
|
141
|
+
self.application.make("builder")
|
|
142
|
+
.new()
|
|
143
|
+
.table(self.guard_config.get("password_reset_table"))
|
|
144
|
+
.where("token", token)
|
|
145
|
+
.first()
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
if not reset_record:
|
|
149
|
+
return False
|
|
150
|
+
|
|
151
|
+
auth_config = self.get_config_options()
|
|
152
|
+
(
|
|
153
|
+
self.get_guard()
|
|
154
|
+
.set_options(auth_config)
|
|
155
|
+
.reset_password(reset_record.get("email"), password)
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
(
|
|
159
|
+
self.application.make("builder")
|
|
160
|
+
.new()
|
|
161
|
+
.table(self.guard_config.get("password_reset_table"))
|
|
162
|
+
.where("token", token)
|
|
163
|
+
.delete()
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
return True
|
|
167
|
+
|
|
168
|
+
@classmethod
|
|
169
|
+
def routes(self):
|
|
170
|
+
return [
|
|
171
|
+
Route.get("/login", "auth.LoginController@show").name("login"),
|
|
172
|
+
Route.get("/logout", "auth.LoginController@logout").name("logout"),
|
|
173
|
+
Route.get("/home", "auth.HomeController@show")
|
|
174
|
+
.name("auth.home")
|
|
175
|
+
.middleware("auth"),
|
|
176
|
+
Route.get("/register", "auth.RegisterController@show").name("register"),
|
|
177
|
+
Route.post("/register", "auth.RegisterController@store").name(
|
|
178
|
+
"register.store"
|
|
179
|
+
),
|
|
180
|
+
Route.get("/password_reset", "auth.PasswordResetController@show").name(
|
|
181
|
+
"password_reset"
|
|
182
|
+
),
|
|
183
|
+
Route.post("/password_reset", "auth.PasswordResetController@store").name(
|
|
184
|
+
"password_reset.store"
|
|
185
|
+
),
|
|
186
|
+
Route.get(
|
|
187
|
+
"/change_password/@token",
|
|
188
|
+
"auth.PasswordResetController@change_password",
|
|
189
|
+
).name("change_password"),
|
|
190
|
+
Route.post(
|
|
191
|
+
"/change_password/@token",
|
|
192
|
+
"auth.PasswordResetController@store_changed_password",
|
|
193
|
+
).name("change_password.store"),
|
|
194
|
+
Route.post("/login", "auth.LoginController@store").name("login.store"),
|
|
195
|
+
]
|