├── .editorconfig ├── .github └── workflows │ └── test.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── docs ├── 00-GETTING-STARTED.md ├── 01-INSTALLATION.md ├── 02-GENERAL-SETUP.md ├── 03-USER.md ├── 04-USER-SETTINGS.md ├── 05-USER-OPTIONS.md ├── 06-LOGIN.md ├── 07-PASSWORD-RESET.md ├── 08-AUTHORIZATION.md ├── 09-EMAIL-CONFIRMATION.md ├── 10-BEARER-LOGIN.md ├── 11-OAUTH.md ├── 12-ACTION-HELPERS.md ├── 13-ACTION-PIPES.md ├── 14-I18N.md └── 15-TESTING.md ├── shard.edge.yml ├── shard.latest.yml ├── shard.yml ├── spec ├── setup │ ├── database.cr │ ├── email.cr │ ├── server.cr │ └── webmock.cr ├── shield │ ├── actions │ │ ├── action_pipes_spec.cr │ │ ├── api │ │ │ ├── bearer_login_helpers_spec.cr │ │ │ ├── bearer_login_pipes_spec.cr │ │ │ ├── bearer_logins │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ ├── index_spec.cr │ │ │ │ ├── show_spec.cr │ │ │ │ ├── token │ │ │ │ │ └── verify_spec.cr │ │ │ │ └── update_spec.cr │ │ │ ├── current_login │ │ │ │ ├── create_spec.cr │ │ │ │ ├── delete_spec.cr │ │ │ │ └── destroy_spec.cr │ │ │ ├── current_user │ │ │ │ ├── bearer_logins │ │ │ │ │ ├── create_spec.cr │ │ │ │ │ ├── delete_spec.cr │ │ │ │ │ ├── destroy_spec.cr │ │ │ │ │ └── index_spec.cr │ │ │ │ ├── create_spec.cr │ │ │ │ ├── email_confirmations │ │ │ │ │ ├── delete_spec.cr │ │ │ │ │ ├── destroy_spec.cr │ │ │ │ │ └── index_spec.cr │ │ │ │ ├── logins │ │ │ │ │ ├── delete_spec.cr │ │ │ │ │ ├── destroy_spec.cr │ │ │ │ │ └── index_spec.cr │ │ │ │ ├── oauth_access_tokens │ │ │ │ │ ├── delete_spec.cr │ │ │ │ │ ├── destroy_spec.cr │ │ │ │ │ └── index_spec.cr │ │ │ │ ├── oauth_clients │ │ │ │ │ ├── create_spec.cr │ │ │ │ │ ├── delete_spec.cr │ │ │ │ │ ├── destroy_spec.cr │ │ │ │ │ └── index_spec.cr │ │ │ │ ├── oauth_grants │ │ │ │ │ ├── delete_spec.cr │ │ │ │ │ ├── destroy_spec.cr │ │ │ │ │ └── index_spec.cr │ │ │ │ ├── oauth_permissions │ │ │ │ │ ├── delete_spec.cr │ │ │ │ │ ├── destroy_spec.cr │ │ │ │ │ └── index_spec.cr │ │ │ │ ├── password_resets │ │ │ │ │ ├── delete_spec.cr │ │ │ │ │ ├── destroy_spec.cr │ │ │ │ │ └── index_spec.cr │ │ │ │ ├── show_spec.cr │ │ │ │ └── update_spec.cr │ │ │ ├── email_confirmation_current_user │ │ │ │ ├── create_spec.cr │ │ │ │ ├── show_spec.cr │ │ │ │ └── update_spec.cr │ │ │ ├── email_confirmation_pipes_spec.cr │ │ │ ├── email_confirmations │ │ │ │ ├── create_spec.cr │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ ├── index_spec.cr │ │ │ │ ├── show_spec.cr │ │ │ │ ├── token │ │ │ │ │ └── verify_spec.cr │ │ │ │ └── update_spec.cr │ │ │ ├── login_helpers_spec.cr │ │ │ ├── login_pipes_spec.cr │ │ │ ├── logins │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ ├── index_spec.cr │ │ │ │ ├── show_spec.cr │ │ │ │ └── token │ │ │ │ │ └── verify_spec.cr │ │ │ ├── oauth │ │ │ │ ├── authorization │ │ │ │ │ ├── create_spec.cr │ │ │ │ │ └── pipes_spec.cr │ │ │ │ └── token │ │ │ │ │ ├── create_spec.cr │ │ │ │ │ ├── delete_spec.cr │ │ │ │ │ ├── destroy_spec.cr │ │ │ │ │ ├── pipes_spec.cr │ │ │ │ │ └── verify_spec.cr │ │ │ ├── oauth_access_tokens │ │ │ │ └── index_spec.cr │ │ │ ├── oauth_clients │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ ├── index_spec.cr │ │ │ │ ├── secret │ │ │ │ │ └── update_spec.cr │ │ │ │ ├── show_spec.cr │ │ │ │ ├── update_spec.cr │ │ │ │ └── users │ │ │ │ │ └── index_spec.cr │ │ │ ├── oauth_grants │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ ├── index_spec.cr │ │ │ │ └── show_spec.cr │ │ │ ├── password_reset_pipes_spec.cr │ │ │ ├── password_resets │ │ │ │ ├── create_spec.cr │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ ├── index_spec.cr │ │ │ │ ├── show_spec.cr │ │ │ │ ├── token │ │ │ │ │ └── verify_spec.cr │ │ │ │ └── update_spec.cr │ │ │ └── users │ │ │ │ ├── bearer_logins │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ └── index_spec.cr │ │ │ │ ├── create_spec.cr │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── email_confirmations │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ └── index_spec.cr │ │ │ │ ├── index_spec.cr │ │ │ │ ├── logins │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ └── index_spec.cr │ │ │ │ ├── oauth_access_tokens │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ └── index_spec.cr │ │ │ │ ├── oauth_clients │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ └── index_spec.cr │ │ │ │ ├── oauth_grants │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ └── index_spec.cr │ │ │ │ ├── oauth_permissions │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ └── index_spec.cr │ │ │ │ ├── password_resets │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ └── index_spec.cr │ │ │ │ ├── show_spec.cr │ │ │ │ └── update_spec.cr │ │ ├── bearer_logins │ │ │ ├── delete_spec.cr │ │ │ ├── destroy_spec.cr │ │ │ ├── edit_spec.cr │ │ │ ├── index_spec.cr │ │ │ ├── show_spec.cr │ │ │ ├── token │ │ │ │ └── show_spec.cr │ │ │ └── update_spec.cr │ │ ├── current_login │ │ │ ├── create_spec.cr │ │ │ ├── delete_spec.cr │ │ │ ├── destroy_spec.cr │ │ │ └── new_spec.cr │ │ ├── current_user │ │ │ ├── bearer_logins │ │ │ │ ├── create_spec.cr │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ ├── index_spec.cr │ │ │ │ └── new_spec.cr │ │ │ ├── create_spec.cr │ │ │ ├── edit_spec.cr │ │ │ ├── email_confirmations │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ └── index_spec.cr │ │ │ ├── logins │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ └── index_spec.cr │ │ │ ├── new_spec.cr │ │ │ ├── oauth_access_tokens │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ └── index_spec.cr │ │ │ ├── oauth_clients │ │ │ │ ├── create_spec.cr │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ ├── index_spec.cr │ │ │ │ └── new_spec.cr │ │ │ ├── oauth_grants │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ └── index_spec.cr │ │ │ ├── oauth_permissions │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ └── index_spec.cr │ │ │ ├── password_resets │ │ │ │ ├── delete_spec.cr │ │ │ │ ├── destroy_spec.cr │ │ │ │ └── index_spec.cr │ │ │ ├── show_spec.cr │ │ │ └── update_spec.cr │ │ ├── email_confirmation_current_user │ │ │ ├── create_spec.cr │ │ │ ├── edit_spec.cr │ │ │ ├── new_spec.cr │ │ │ ├── show_spec.cr │ │ │ └── update_spec.cr │ │ ├── email_confirmation_pipes_spec.cr │ │ ├── email_confirmations │ │ │ ├── create_spec.cr │ │ │ ├── delete_spec.cr │ │ │ ├── destroy_spec.cr │ │ │ ├── index_spec.cr │ │ │ ├── new_spec.cr │ │ │ ├── show_spec.cr │ │ │ ├── token │ │ │ │ └── show_spec.cr │ │ │ └── update_spec.cr │ │ ├── login_helpers_spec.cr │ │ ├── login_pipes_spec.cr │ │ ├── logins │ │ │ ├── delete_spec.cr │ │ │ ├── destroy_spec.cr │ │ │ ├── index_spec.cr │ │ │ └── show_spec.cr │ │ ├── oauth │ │ │ ├── authorization │ │ │ │ ├── create_spec.cr │ │ │ │ └── new_spec.cr │ │ │ ├── authorize_spec.cr │ │ │ └── pipes_spec.cr │ │ ├── oauth_access_tokens │ │ │ └── index_spec.cr │ │ ├── oauth_clients │ │ │ ├── delete_spec.cr │ │ │ ├── destroy_spec.cr │ │ │ ├── edit_spec.cr │ │ │ ├── index_spec.cr │ │ │ ├── secret │ │ │ │ ├── show_spec.cr │ │ │ │ └── update_spec.cr │ │ │ ├── show_spec.cr │ │ │ ├── update_spec.cr │ │ │ └── users │ │ │ │ └── index_spec.cr │ │ ├── oauth_grants │ │ │ ├── delete_spec.cr │ │ │ ├── destroy_spec.cr │ │ │ ├── index_spec.cr │ │ │ └── show_spec.cr │ │ ├── password_reset_pipes_spec.cr │ │ ├── password_resets │ │ │ ├── create_spec.cr │ │ │ ├── delete_spec.cr │ │ │ ├── destroy_spec.cr │ │ │ ├── edit_spec.cr │ │ │ ├── index_spec.cr │ │ │ ├── new_spec.cr │ │ │ ├── show_spec.cr │ │ │ ├── token │ │ │ │ └── show_spec.cr │ │ │ └── update_spec.cr │ │ └── users │ │ │ ├── bearer_logins │ │ │ ├── delete_spec.cr │ │ │ ├── destroy_spec.cr │ │ │ └── index_spec.cr │ │ │ ├── create_spec.cr │ │ │ ├── delete_spec.cr │ │ │ ├── edit_spec.cr │ │ │ ├── email_confirmations │ │ │ ├── delete_spec.cr │ │ │ ├── destroy_spec.cr │ │ │ └── index_spec.cr │ │ │ ├── index_spec.cr │ │ │ ├── logins │ │ │ ├── delete_spec.cr │ │ │ ├── destroy_spec.cr │ │ │ └── index_spec.cr │ │ │ ├── new_spec.cr │ │ │ ├── oauth_access_tokens │ │ │ ├── delete_spec.cr │ │ │ ├── destroy_spec.cr │ │ │ └── index_spec.cr │ │ │ ├── oauth_clients │ │ │ ├── delete_spec.cr │ │ │ ├── destroy_spec.cr │ │ │ └── index_spec.cr │ │ │ ├── oauth_grants │ │ │ ├── delete_spec.cr │ │ │ ├── destroy_spec.cr │ │ │ └── index_spec.cr │ │ │ ├── oauth_permissions │ │ │ ├── delete_spec.cr │ │ │ ├── destroy_spec.cr │ │ │ └── index_spec.cr │ │ │ ├── password_resets │ │ │ ├── delete_spec.cr │ │ │ ├── destroy_spec.cr │ │ │ └── index_spec.cr │ │ │ ├── show_spec.cr │ │ │ └── update_spec.cr │ ├── operations │ │ ├── create_bearer_login_spec.cr │ │ ├── create_oauth_access_token_from_client_spec.cr │ │ ├── create_oauth_access_token_from_grant_spec.cr │ │ ├── deactivate_oauth_client_spec.cr │ │ ├── deactivate_user_oauth_clients_spec.cr │ │ ├── delete_oauth_permission_spec.cr │ │ ├── delete_user_bearer_logins_spec.cr │ │ ├── delete_user_email_confirmations_spec.cr │ │ ├── delete_user_logins_spec.cr │ │ ├── delete_user_oauth_access_tokens_spec.cr │ │ ├── delete_user_oauth_clients_spec.cr │ │ ├── delete_user_oauth_grants_spec.cr │ │ ├── delete_user_password_resets_spec.cr │ │ ├── delete_user_spec.cr │ │ ├── end_email_confirmation_spec.cr │ │ ├── end_login_spec.cr │ │ ├── end_oauth_grant_gracefully_spec.cr │ │ ├── end_password_reset_spec.cr │ │ ├── end_user_email_confirmations_spec.cr │ │ ├── end_user_logins_spec.cr │ │ ├── end_user_oauth_grants_spec.cr │ │ ├── end_user_password_resets_spec.cr │ │ ├── mixins │ │ │ ├── delete_user_logins_on_password_change_spec.cr │ │ │ ├── end_user_logins_on_password_change_spec.cr │ │ │ ├── notify_bearer_login_if_set_spec.cr │ │ │ ├── notify_bearer_login_spec.cr │ │ │ ├── notify_login_if_set_spec.cr │ │ │ ├── notify_login_spec.cr │ │ │ ├── notify_oauth_access_token_if_set_spec.cr │ │ │ ├── notify_oauth_access_token_spec.cr │ │ │ ├── notify_password_change_if_set_spec.cr │ │ │ ├── notify_password_change_spec.cr │ │ │ ├── save_user_settings_spec.cr │ │ │ ├── send_welcome_email_spec.cr │ │ │ ├── validate_bearer_login_spec.cr │ │ │ ├── validate_email_confirmation_spec.cr │ │ │ ├── validate_login_spec.cr │ │ │ ├── validate_oauth_client_spec.cr │ │ │ ├── validate_oauth_grant_spec.cr │ │ │ ├── validate_password_reset_spec.cr │ │ │ ├── validate_password_spec.cr │ │ │ └── validate_user_spec.cr │ │ ├── register_email_confirmation_user_spec.cr │ │ ├── register_oauth_client_spec.cr │ │ ├── register_user_spec.cr │ │ ├── reset_password_spec.cr │ │ ├── revoke_bearer_login_spec.cr │ │ ├── revoke_oauth_permission_spec.cr │ │ ├── revoke_oauth_token_spec.cr │ │ ├── revoke_user_bearer_logins_spec.cr │ │ ├── revoke_user_oauth_access_tokens_spec.cr │ │ ├── rotate_oauth_client_secret_spec.cr │ │ ├── rotate_oauth_grant_spec.cr │ │ ├── save_user_options_spec.cr │ │ ├── start_email_confirmation_spec.cr │ │ ├── start_login_spec.cr │ │ ├── start_oauth_grant_spec.cr │ │ ├── start_password_reset_spec.cr │ │ ├── update_bearer_login_spec.cr │ │ ├── update_confirmed_email_spec.cr │ │ ├── update_email_confirmation_user_spec.cr │ │ ├── update_oauth_client_spec.cr │ │ ├── update_password_spec.cr │ │ └── update_user_spec.cr │ └── utilities │ │ └── mixins │ │ ├── basic_credentials_spec.cr │ │ ├── bearer_credentials_spec.cr │ │ ├── bearer_login_verifier_spec.cr │ │ ├── email_confirmation_verifier_spec.cr │ │ ├── login_verifier_spec.cr │ │ ├── oauth_client_verifier_spec.cr │ │ ├── oauth_grant_verifier_spec.cr │ │ └── password_reset_verifier_spec.cr ├── spec_helper.cr └── support │ ├── api_client.cr │ ├── app │ ├── config │ │ ├── cookies.cr │ │ ├── database.cr │ │ ├── email.cr │ │ ├── env.cr │ │ ├── error_handler.cr │ │ ├── i18n.cr │ │ ├── route_helper.cr │ │ ├── server.cr │ │ └── shield.cr │ ├── db │ │ └── migrations │ │ │ ├── 20230119160301_create_users.cr │ │ │ ├── 20230119160524_create_logins.cr │ │ │ ├── 20230119160731_create_password_resets.cr │ │ │ ├── 20230119160922_create_email_confirmations.cr │ │ │ ├── 20230119161015_create_bearer_logins.cr │ │ │ ├── 20230119161205_create_oauth_clients.cr │ │ │ ├── 20230119161548_add_bearer_logins_oauth_client_id.cr │ │ │ ├── 20230119161716_create_oauth_grants.cr │ │ │ ├── 20230119175313_create_user_options.cr │ │ │ └── 20230119175638_add_user_settings.cr │ ├── src │ │ ├── actions │ │ │ ├── about │ │ │ │ ├── create.cr │ │ │ │ ├── index.cr │ │ │ │ ├── new.cr │ │ │ │ └── update.cr │ │ │ ├── api │ │ │ │ ├── bearer_logins │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ ├── index.cr │ │ │ │ │ ├── show.cr │ │ │ │ │ ├── token │ │ │ │ │ │ └── verify.cr │ │ │ │ │ └── update.cr │ │ │ │ ├── current_login │ │ │ │ │ ├── create.cr │ │ │ │ │ ├── delete.cr │ │ │ │ │ └── destroy.cr │ │ │ │ ├── current_user │ │ │ │ │ ├── bearer_logins │ │ │ │ │ │ ├── create.cr │ │ │ │ │ │ ├── delete.cr │ │ │ │ │ │ ├── destroy.cr │ │ │ │ │ │ └── index.cr │ │ │ │ │ ├── create.cr │ │ │ │ │ ├── email_confirmations │ │ │ │ │ │ ├── delete.cr │ │ │ │ │ │ ├── destroy.cr │ │ │ │ │ │ └── index.cr │ │ │ │ │ ├── logins │ │ │ │ │ │ ├── delete.cr │ │ │ │ │ │ ├── destroy.cr │ │ │ │ │ │ └── index.cr │ │ │ │ │ ├── oauth_access_tokens │ │ │ │ │ │ ├── delete.cr │ │ │ │ │ │ ├── destroy.cr │ │ │ │ │ │ └── index.cr │ │ │ │ │ ├── oauth_clients │ │ │ │ │ │ ├── create.cr │ │ │ │ │ │ ├── delete.cr │ │ │ │ │ │ ├── destroy.cr │ │ │ │ │ │ └── index.cr │ │ │ │ │ ├── oauth_grants │ │ │ │ │ │ ├── delete.cr │ │ │ │ │ │ ├── destroy.cr │ │ │ │ │ │ └── index.cr │ │ │ │ │ ├── oauth_permissions │ │ │ │ │ │ ├── delete.cr │ │ │ │ │ │ ├── destroy.cr │ │ │ │ │ │ └── index.cr │ │ │ │ │ ├── password_resets │ │ │ │ │ │ ├── delete.cr │ │ │ │ │ │ ├── destroy.cr │ │ │ │ │ │ └── index.cr │ │ │ │ │ ├── show.cr │ │ │ │ │ └── update.cr │ │ │ │ ├── email_confirmations │ │ │ │ │ ├── create.cr │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ ├── index.cr │ │ │ │ │ ├── show.cr │ │ │ │ │ ├── token │ │ │ │ │ │ └── verify.cr │ │ │ │ │ └── update.cr │ │ │ │ ├── logins │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ ├── index.cr │ │ │ │ │ ├── show.cr │ │ │ │ │ └── token │ │ │ │ │ │ └── verify.cr │ │ │ │ ├── oauth │ │ │ │ │ ├── authorization │ │ │ │ │ │ └── create.cr │ │ │ │ │ └── token │ │ │ │ │ │ ├── create.cr │ │ │ │ │ │ ├── delete.cr │ │ │ │ │ │ ├── destroy.cr │ │ │ │ │ │ └── verify.cr │ │ │ │ ├── oauth_access_tokens │ │ │ │ │ └── index.cr │ │ │ │ ├── oauth_clients │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ ├── index.cr │ │ │ │ │ ├── secret │ │ │ │ │ │ └── update.cr │ │ │ │ │ ├── show.cr │ │ │ │ │ ├── update.cr │ │ │ │ │ └── users │ │ │ │ │ │ └── index.cr │ │ │ │ ├── oauth_grants │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ ├── index.cr │ │ │ │ │ └── show.cr │ │ │ │ ├── password_resets │ │ │ │ │ ├── create.cr │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ ├── index.cr │ │ │ │ │ ├── show.cr │ │ │ │ │ ├── token │ │ │ │ │ │ └── verify.cr │ │ │ │ │ └── update.cr │ │ │ │ ├── posts │ │ │ │ │ ├── create.cr │ │ │ │ │ ├── index.cr │ │ │ │ │ └── new.cr │ │ │ │ ├── regular_current_user │ │ │ │ │ ├── create.cr │ │ │ │ │ ├── show.cr │ │ │ │ │ └── update.cr │ │ │ │ └── users │ │ │ │ │ ├── bearer_logins │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ └── index.cr │ │ │ │ │ ├── create.cr │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── email_confirmations │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ └── index.cr │ │ │ │ │ ├── index.cr │ │ │ │ │ ├── logins │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ └── index.cr │ │ │ │ │ ├── oauth_access_tokens │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ └── index.cr │ │ │ │ │ ├── oauth_clients │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ └── index.cr │ │ │ │ │ ├── oauth_grants │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ └── index.cr │ │ │ │ │ ├── oauth_permissions │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ └── index.cr │ │ │ │ │ ├── password_resets │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ └── index.cr │ │ │ │ │ ├── show.cr │ │ │ │ │ └── update.cr │ │ │ ├── api_action.cr │ │ │ ├── bearer_logins │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ ├── edit.cr │ │ │ │ ├── index.cr │ │ │ │ ├── show.cr │ │ │ │ ├── token │ │ │ │ │ └── show.cr │ │ │ │ └── update.cr │ │ │ ├── browser_action.cr │ │ │ ├── current_login │ │ │ │ ├── create.cr │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── new.cr │ │ │ ├── current_user │ │ │ │ ├── bearer_logins │ │ │ │ │ ├── create.cr │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ ├── index.cr │ │ │ │ │ └── new.cr │ │ │ │ ├── create.cr │ │ │ │ ├── edit.cr │ │ │ │ ├── email_confirmations │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ └── index.cr │ │ │ │ ├── logins │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ └── index.cr │ │ │ │ ├── new.cr │ │ │ │ ├── oauth_access_tokens │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ └── index.cr │ │ │ │ ├── oauth_clients │ │ │ │ │ ├── create.cr │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ ├── index.cr │ │ │ │ │ └── new.cr │ │ │ │ ├── oauth_grants │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ └── index.cr │ │ │ │ ├── oauth_permissions │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ └── index.cr │ │ │ │ ├── password_resets │ │ │ │ │ ├── delete.cr │ │ │ │ │ ├── destroy.cr │ │ │ │ │ └── index.cr │ │ │ │ ├── show.cr │ │ │ │ └── update.cr │ │ │ ├── email_confirmations │ │ │ │ ├── create.cr │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ ├── index.cr │ │ │ │ ├── new.cr │ │ │ │ ├── show.cr │ │ │ │ ├── token │ │ │ │ │ └── show.cr │ │ │ │ └── update.cr │ │ │ ├── errors │ │ │ │ └── show.cr │ │ │ ├── home │ │ │ │ ├── create.cr │ │ │ │ ├── edit.cr │ │ │ │ ├── index.cr │ │ │ │ ├── show.cr │ │ │ │ └── update.cr │ │ │ ├── logins │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ ├── index.cr │ │ │ │ └── show.cr │ │ │ ├── oauth │ │ │ │ ├── authorization │ │ │ │ │ ├── create.cr │ │ │ │ │ └── new.cr │ │ │ │ └── authorize.cr │ │ │ ├── oauth_access_tokens │ │ │ │ └── index.cr │ │ │ ├── oauth_clients │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ ├── edit.cr │ │ │ │ ├── index.cr │ │ │ │ ├── secret │ │ │ │ │ ├── show.cr │ │ │ │ │ └── update.cr │ │ │ │ ├── show.cr │ │ │ │ ├── update.cr │ │ │ │ └── users │ │ │ │ │ └── index.cr │ │ │ ├── oauth_grants │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ ├── index.cr │ │ │ │ └── show.cr │ │ │ ├── password_resets │ │ │ │ ├── create.cr │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ ├── edit.cr │ │ │ │ ├── index.cr │ │ │ │ ├── new.cr │ │ │ │ ├── show.cr │ │ │ │ ├── token │ │ │ │ │ └── show.cr │ │ │ │ └── update.cr │ │ │ ├── posts │ │ │ │ └── new.cr │ │ │ ├── regular_current_user │ │ │ │ ├── create.cr │ │ │ │ ├── edit.cr │ │ │ │ ├── new.cr │ │ │ │ ├── show.cr │ │ │ │ └── update.cr │ │ │ └── users │ │ │ │ ├── bearer_logins │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── index.cr │ │ │ │ ├── create.cr │ │ │ │ ├── delete.cr │ │ │ │ ├── edit.cr │ │ │ │ ├── email_confirmations │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── index.cr │ │ │ │ ├── index.cr │ │ │ │ ├── logins │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── index.cr │ │ │ │ ├── new.cr │ │ │ │ ├── oauth_access_tokens │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── index.cr │ │ │ │ ├── oauth_clients │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── index.cr │ │ │ │ ├── oauth_grants │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── index.cr │ │ │ │ ├── oauth_permissions │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── index.cr │ │ │ │ ├── password_resets │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── index.cr │ │ │ │ ├── show.cr │ │ │ │ └── update.cr │ │ ├── app.cr │ │ ├── app_database.cr │ │ ├── app_server.cr │ │ ├── emails │ │ │ ├── base_email.cr │ │ │ ├── bearer_login_notification_email.cr │ │ │ ├── email_confirmation_request_email.cr │ │ │ ├── guest_password_reset_request_email.cr │ │ │ ├── login_notification_email.cr │ │ │ ├── oauth_access_token_notification_email.cr │ │ │ ├── password_change_notification_email.cr │ │ │ ├── password_reset_request_email.cr │ │ │ ├── user_email_confirmation_request_email.cr │ │ │ ├── user_welcome_email.cr │ │ │ └── welcome_email.cr │ │ ├── models │ │ │ ├── base_model.cr │ │ │ ├── bearer_login.cr │ │ │ ├── email_confirmation.cr │ │ │ ├── login.cr │ │ │ ├── oauth_client.cr │ │ │ ├── oauth_grant.cr │ │ │ ├── password_reset.cr │ │ │ ├── user.cr │ │ │ ├── user_options.cr │ │ │ └── user_settings.cr │ │ ├── operations │ │ │ ├── create_bearer_login_with_settings.cr │ │ │ ├── log_user_in_with_settings.cr │ │ │ ├── register_current_user.cr │ │ │ ├── register_current_user_2.cr │ │ │ ├── register_regular_current_user.cr │ │ │ ├── register_regular_current_user_2.cr │ │ │ ├── register_user.cr │ │ │ ├── register_user_with_settings.cr │ │ │ ├── save_user_options_2.cr │ │ │ ├── update_current_user.cr │ │ │ ├── update_current_user_2.cr │ │ │ ├── update_current_user_with_settings.cr │ │ │ ├── update_regular_current_user.cr │ │ │ ├── update_regular_current_user_2.cr │ │ │ ├── update_user.cr │ │ │ └── update_user_with_settings.cr │ │ ├── pages │ │ │ ├── bearer_logins │ │ │ │ ├── edit_page.cr │ │ │ │ ├── index_page.cr │ │ │ │ ├── show_page.cr │ │ │ │ └── token │ │ │ │ │ └── show_page.cr │ │ │ ├── current_login │ │ │ │ └── new_page.cr │ │ │ ├── current_user │ │ │ │ ├── bearer_logins │ │ │ │ │ ├── index_page.cr │ │ │ │ │ └── new_page.cr │ │ │ │ ├── edit_page.cr │ │ │ │ ├── email_confirmations │ │ │ │ │ └── index_page.cr │ │ │ │ ├── logins │ │ │ │ │ └── index_page.cr │ │ │ │ ├── new_page.cr │ │ │ │ ├── oauth_clients │ │ │ │ │ ├── index_page.cr │ │ │ │ │ └── new_page.cr │ │ │ │ ├── oauth_grants │ │ │ │ │ └── index_page.cr │ │ │ │ ├── oauth_permissions │ │ │ │ │ └── index_page.cr │ │ │ │ ├── password_resets │ │ │ │ │ └── index_page.cr │ │ │ │ └── show_page.cr │ │ │ ├── email_confirmations │ │ │ │ ├── index_page.cr │ │ │ │ ├── new_page.cr │ │ │ │ └── show_page.cr │ │ │ ├── logins │ │ │ │ ├── index_page.cr │ │ │ │ └── show_page.cr │ │ │ ├── main_layout.cr │ │ │ ├── oauth │ │ │ │ └── authorization │ │ │ │ │ └── new_page.cr │ │ │ ├── oauth_clients │ │ │ │ ├── edit_page.cr │ │ │ │ ├── index_page.cr │ │ │ │ ├── secret │ │ │ │ │ └── show_page.cr │ │ │ │ ├── show_page.cr │ │ │ │ └── users │ │ │ │ │ └── index_page.cr │ │ │ ├── oauth_grants │ │ │ │ ├── index_page.cr │ │ │ │ └── show_page.cr │ │ │ ├── password_resets │ │ │ │ ├── edit_page.cr │ │ │ │ ├── index_page.cr │ │ │ │ ├── new_page.cr │ │ │ │ └── show_page.cr │ │ │ ├── regular_current_user │ │ │ │ ├── edit_page.cr │ │ │ │ ├── new_page.cr │ │ │ │ └── show_page.cr │ │ │ └── users │ │ │ │ ├── bearer_logins │ │ │ │ └── index_page.cr │ │ │ │ ├── edit_page.cr │ │ │ │ ├── email_confirmations │ │ │ │ └── index_page.cr │ │ │ │ ├── index_page.cr │ │ │ │ ├── logins │ │ │ │ └── index_page.cr │ │ │ │ ├── new_page.cr │ │ │ │ ├── oauth_clients │ │ │ │ └── index_page.cr │ │ │ │ ├── oauth_grants │ │ │ │ └── index_page.cr │ │ │ │ ├── oauth_permissions │ │ │ │ └── index_page.cr │ │ │ │ ├── password_resets │ │ │ │ └── index_page.cr │ │ │ │ └── show_page.cr │ │ └── serializers │ │ │ ├── base_serializer.cr │ │ │ ├── bearer_login_serializer.cr │ │ │ ├── email_confirmation_serializer.cr │ │ │ ├── error_serializer.cr │ │ │ ├── failure_serializer.cr │ │ │ ├── login_serializer.cr │ │ │ ├── oauth_client_serializer.cr │ │ │ ├── oauth_grant_serializer.cr │ │ │ ├── password_reset_serializer.cr │ │ │ ├── success_serializer.cr │ │ │ └── user_serializer.cr │ └── tasks.cr │ ├── boot.cr │ └── factories │ ├── bearer_login_factory.cr │ ├── email_confirmation_factory.cr │ ├── login_factory.cr │ ├── oauth_client_factory.cr │ ├── oauth_grant_factory.cr │ ├── password_reset_factory.cr │ ├── user_factory.cr │ └── user_options_factory.cr └── src ├── charms.cr ├── config.cr ├── presets.cr ├── presets ├── bearer_login.cr ├── common.cr ├── email_confirmation.cr ├── login.cr ├── oauth_client.cr ├── oauth_grant.cr ├── password_reset.cr ├── user.cr └── user_options.cr ├── shield.cr ├── shield ├── actions │ ├── api │ │ ├── bearer_logins │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ ├── index.cr │ │ │ ├── show.cr │ │ │ ├── token │ │ │ │ └── verify.cr │ │ │ └── update.cr │ │ ├── current_login │ │ │ ├── create.cr │ │ │ ├── delete.cr │ │ │ └── destroy.cr │ │ ├── current_user │ │ │ ├── bearer_logins │ │ │ │ ├── create.cr │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── index.cr │ │ │ ├── create.cr │ │ │ ├── email_confirmations │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── index.cr │ │ │ ├── logins │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── index.cr │ │ │ ├── oauth_access_tokens │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── index.cr │ │ │ ├── oauth_clients │ │ │ │ ├── create.cr │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── index.cr │ │ │ ├── oauth_grants │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── index.cr │ │ │ ├── oauth_permissions │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── index.cr │ │ │ ├── password_resets │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ └── index.cr │ │ │ ├── show.cr │ │ │ └── update.cr │ │ ├── email_confirmation_current_user │ │ │ ├── create.cr │ │ │ ├── show.cr │ │ │ └── update.cr │ │ ├── email_confirmations │ │ │ ├── create.cr │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ ├── index.cr │ │ │ ├── show.cr │ │ │ ├── token │ │ │ │ └── verify.cr │ │ │ └── update.cr │ │ ├── logins │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ ├── index.cr │ │ │ ├── show.cr │ │ │ └── token │ │ │ │ └── verify.cr │ │ ├── mixins │ │ │ ├── bearer_login_helpers.cr │ │ │ ├── bearer_login_pipes.cr │ │ │ ├── email_confirmation_helpers.cr │ │ │ ├── email_confirmation_pipes.cr │ │ │ ├── login_helpers.cr │ │ │ ├── login_pipes.cr │ │ │ ├── password_reset_helpers.cr │ │ │ ├── password_reset_pipes.cr │ │ │ └── skip_authentication_cache.cr │ │ ├── oauth │ │ │ ├── authorization │ │ │ │ ├── create.cr │ │ │ │ └── pipes.cr │ │ │ └── token │ │ │ │ ├── create.cr │ │ │ │ ├── delete.cr │ │ │ │ ├── destroy.cr │ │ │ │ ├── pipes.cr │ │ │ │ └── verify.cr │ │ ├── oauth_access_tokens │ │ │ └── index.cr │ │ ├── oauth_clients │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ ├── index.cr │ │ │ ├── secret │ │ │ │ └── update.cr │ │ │ ├── show.cr │ │ │ ├── update.cr │ │ │ └── users │ │ │ │ └── index.cr │ │ ├── oauth_grants │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ ├── index.cr │ │ │ └── show.cr │ │ ├── password_resets │ │ │ ├── create.cr │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ ├── index.cr │ │ │ ├── show.cr │ │ │ ├── token │ │ │ │ └── verify.cr │ │ │ └── update.cr │ │ └── users │ │ │ ├── bearer_logins │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ └── index.cr │ │ │ ├── create.cr │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ ├── email_confirmations │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ └── index.cr │ │ │ ├── index.cr │ │ │ ├── logins │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ └── index.cr │ │ │ ├── oauth_access_tokens │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ └── index.cr │ │ │ ├── oauth_clients │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ └── index.cr │ │ │ ├── oauth_grants │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ └── index.cr │ │ │ ├── oauth_permissions │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ └── index.cr │ │ │ ├── password_resets │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ └── index.cr │ │ │ ├── show.cr │ │ │ └── update.cr │ ├── api_action.cr │ ├── bearer_logins │ │ ├── delete.cr │ │ ├── destroy.cr │ │ ├── edit.cr │ │ ├── index.cr │ │ ├── show.cr │ │ ├── token │ │ │ └── show.cr │ │ └── update.cr │ ├── browser_action.cr │ ├── current_login │ │ ├── create.cr │ │ ├── delete.cr │ │ ├── destroy.cr │ │ └── new.cr │ ├── current_user │ │ ├── bearer_logins │ │ │ ├── create.cr │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ ├── index.cr │ │ │ └── new.cr │ │ ├── create.cr │ │ ├── edit.cr │ │ ├── email_confirmations │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ └── index.cr │ │ ├── logins │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ └── index.cr │ │ ├── new.cr │ │ ├── oauth_access_tokens │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ └── index.cr │ │ ├── oauth_clients │ │ │ ├── create.cr │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ ├── index.cr │ │ │ └── new.cr │ │ ├── oauth_grants │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ └── index.cr │ │ ├── oauth_permissions │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ └── index.cr │ │ ├── password_resets │ │ │ ├── delete.cr │ │ │ ├── destroy.cr │ │ │ └── index.cr │ │ ├── show.cr │ │ └── update.cr │ ├── email_confirmation_current_user │ │ ├── create.cr │ │ ├── edit.cr │ │ ├── new.cr │ │ ├── show.cr │ │ └── update.cr │ ├── email_confirmations │ │ ├── create.cr │ │ ├── delete.cr │ │ ├── destroy.cr │ │ ├── index.cr │ │ ├── new.cr │ │ ├── show.cr │ │ ├── token │ │ │ └── show.cr │ │ └── update.cr │ ├── logins │ │ ├── delete.cr │ │ ├── destroy.cr │ │ ├── index.cr │ │ └── show.cr │ ├── mixins │ │ ├── action_helpers.cr │ │ ├── action_pipes.cr │ │ ├── email_confirmation_helpers.cr │ │ ├── email_confirmation_pipes.cr │ │ ├── login_helpers.cr │ │ ├── login_pipes.cr │ │ ├── password_reset_helpers.cr │ │ ├── password_reset_pipes.cr │ │ └── skip_authentication_cache.cr │ ├── oauth │ │ ├── authorization │ │ │ ├── create.cr │ │ │ ├── new.cr │ │ │ └── pipes.cr │ │ ├── authorize.cr │ │ ├── helpers.cr │ │ └── pipes.cr │ ├── oauth_access_tokens │ │ └── index.cr │ ├── oauth_clients │ │ ├── delete.cr │ │ ├── destroy.cr │ │ ├── edit.cr │ │ ├── index.cr │ │ ├── secret │ │ │ ├── show.cr │ │ │ └── update.cr │ │ ├── show.cr │ │ ├── update.cr │ │ └── users │ │ │ └── index.cr │ ├── oauth_grants │ │ ├── delete.cr │ │ ├── destroy.cr │ │ ├── index.cr │ │ └── show.cr │ ├── password_resets │ │ ├── create.cr │ │ ├── delete.cr │ │ ├── destroy.cr │ │ ├── edit.cr │ │ ├── index.cr │ │ ├── new.cr │ │ ├── show.cr │ │ ├── token │ │ │ └── show.cr │ │ └── update.cr │ └── users │ │ ├── bearer_logins │ │ ├── delete.cr │ │ ├── destroy.cr │ │ └── index.cr │ │ ├── create.cr │ │ ├── delete.cr │ │ ├── destroy.cr │ │ ├── edit.cr │ │ ├── email_confirmations │ │ ├── delete.cr │ │ ├── destroy.cr │ │ └── index.cr │ │ ├── index.cr │ │ ├── logins │ │ ├── delete.cr │ │ ├── destroy.cr │ │ └── index.cr │ │ ├── new.cr │ │ ├── oauth_access_tokens │ │ ├── delete.cr │ │ ├── destroy.cr │ │ └── index.cr │ │ ├── oauth_clients │ │ ├── delete.cr │ │ ├── destroy.cr │ │ └── index.cr │ │ ├── oauth_grants │ │ ├── delete.cr │ │ ├── destroy.cr │ │ └── index.cr │ │ ├── oauth_permissions │ │ ├── delete.cr │ │ ├── destroy.cr │ │ └── index.cr │ │ ├── password_resets │ │ ├── delete.cr │ │ ├── destroy.cr │ │ └── index.cr │ │ ├── show.cr │ │ └── update.cr ├── http_client.cr ├── models │ ├── bearer_login.cr │ ├── email_confirmation.cr │ ├── login.cr │ ├── mixins │ │ ├── bearer_login_user_options_columns.cr │ │ ├── bearer_login_user_settings.cr │ │ ├── belongs_to_oauth_client.cr │ │ ├── belongs_to_user.cr │ │ ├── has_many_bearer_logins.cr │ │ ├── has_many_email_confirmations.cr │ │ ├── has_many_logins.cr │ │ ├── has_many_oauth_clients.cr │ │ ├── has_many_oauth_grants.cr │ │ ├── has_many_password_resets.cr │ │ ├── has_one_user_options.cr │ │ ├── ip_address_column.cr │ │ ├── login_user_options_columns.cr │ │ ├── login_user_settings.cr │ │ ├── oauth_client_user_options_columns.cr │ │ ├── oauth_client_user_settings.cr │ │ ├── optional_belongs_to_oauth_client.cr │ │ ├── optional_belongs_to_user.cr │ │ └── user_settings_column.cr │ ├── model.cr │ ├── oauth_client.cr │ ├── oauth_grant.cr │ ├── oauth_grant_metadata.cr │ ├── oauth_grant_type.cr │ ├── password_reset.cr │ ├── user.cr │ ├── user_options.cr │ └── user_settings.cr ├── operations │ ├── create_bearer_login.cr │ ├── create_oauth_access_token_from_client.cr │ ├── create_oauth_access_token_from_grant.cr │ ├── deactivate_oauth_client.cr │ ├── deactivate_user_oauth_clients.cr │ ├── delete_bearer_login.cr │ ├── delete_email_confirmation.cr │ ├── delete_login.cr │ ├── delete_oauth_client.cr │ ├── delete_oauth_grant.cr │ ├── delete_oauth_permission.cr │ ├── delete_oauth_token.cr │ ├── delete_password_reset.cr │ ├── delete_user.cr │ ├── delete_user_bearer_logins.cr │ ├── delete_user_email_confirmations.cr │ ├── delete_user_logins.cr │ ├── delete_user_oauth_access_tokens.cr │ ├── delete_user_oauth_clients.cr │ ├── delete_user_oauth_grants.cr │ ├── delete_user_password_resets.cr │ ├── end_email_confirmation.cr │ ├── end_login.cr │ ├── end_oauth_grant.cr │ ├── end_oauth_grant_gracefully.cr │ ├── end_password_reset.cr │ ├── end_user_email_confirmations.cr │ ├── end_user_logins.cr │ ├── end_user_oauth_grants.cr │ ├── end_user_password_resets.cr │ ├── mixins │ │ ├── delete_access_tokens_after_deactivate_oauth_client.cr │ │ ├── delete_access_tokens_if_oauth_grant_replayed.cr │ │ ├── delete_email_confirmations_after_register_user.cr │ │ ├── delete_email_confirmations_after_update_email.cr │ │ ├── delete_grants_after_deactivate_oauth_client.cr │ │ ├── delete_grants_after_revoke_oauth_permission.cr │ │ ├── delete_oauth_refresh_token.cr │ │ ├── delete_password_resets_after_reset_password.cr │ │ ├── delete_session.cr │ │ ├── delete_user_logins_on_password_change.cr │ │ ├── end_oauth_grants_after_deactivate_oauth_client.cr │ │ ├── end_oauth_grants_after_delete_oauth_permission.cr │ │ ├── end_user_logins_on_password_change.cr │ │ ├── has_one_save_user_options.cr │ │ ├── notify_bearer_login.cr │ │ ├── notify_bearer_login_if_set.cr │ │ ├── notify_login.cr │ │ ├── notify_login_if_set.cr │ │ ├── notify_oauth_access_token.cr │ │ ├── notify_oauth_access_token_if_set.cr │ │ ├── notify_password_change.cr │ │ ├── notify_password_change_if_set.cr │ │ ├── revoke_oauth_refresh_token.cr │ │ ├── save_bearer_login_user_options.cr │ │ ├── save_bearer_login_user_settings.cr │ │ ├── save_login_user_options.cr │ │ ├── save_login_user_settings.cr │ │ ├── save_oauth_client_user_options.cr │ │ ├── save_oauth_client_user_settings.cr │ │ ├── save_user_settings.cr │ │ ├── send_welcome_email.cr │ │ ├── set_email_from_email_confirmation.cr │ │ ├── set_ip_address_from_remote_address.cr │ │ ├── set_oauth_client_id_from_oauth_client.cr │ │ ├── set_oauth_grant_code.cr │ │ ├── set_password_digest_from_password.cr │ │ ├── set_secret.cr │ │ ├── set_session.cr │ │ ├── set_token.cr │ │ ├── set_user_email.cr │ │ ├── validate_bearer_login.cr │ │ ├── validate_email_confirmation.cr │ │ ├── validate_login.cr │ │ ├── validate_oauth_access_token.cr │ │ ├── validate_oauth_client.cr │ │ ├── validate_oauth_grant.cr │ │ ├── validate_password.cr │ │ ├── validate_password_reset.cr │ │ └── validate_user.cr │ ├── register_email_confirmation_user.cr │ ├── register_oauth_client.cr │ ├── register_user.cr │ ├── reset_password.cr │ ├── revoke_bearer_login.cr │ ├── revoke_oauth_permission.cr │ ├── revoke_oauth_token.cr │ ├── revoke_user_bearer_logins.cr │ ├── revoke_user_oauth_access_tokens.cr │ ├── rotate_oauth_client_secret.cr │ ├── rotate_oauth_grant.cr │ ├── save_user_options.cr │ ├── start_email_confirmation.cr │ ├── start_login.cr │ ├── start_oauth_grant.cr │ ├── start_password_reset.cr │ ├── update_bearer_login.cr │ ├── update_confirmed_email.cr │ ├── update_email_confirmation_user.cr │ ├── update_oauth_client.cr │ ├── update_password.cr │ └── update_user.cr ├── queries │ ├── bearer_login_query.cr │ ├── email_confirmation_query.cr │ ├── login_query.cr │ ├── mixins │ │ └── .keep │ ├── oauth_client_query.cr │ ├── oauth_grant_query.cr │ ├── password_reset_query.cr │ ├── user_options_query.cr │ └── user_query.cr ├── utilities │ ├── bcrypt_hash.cr │ ├── bearer_login_credentials.cr │ ├── bearer_login_headers.cr │ ├── bearer_login_params.cr │ ├── bearer_scope.cr │ ├── bearer_token_session.cr │ ├── email_confirmation_credentials.cr │ ├── email_confirmation_params.cr │ ├── email_confirmation_session.cr │ ├── login_credentials.cr │ ├── login_headers.cr │ ├── login_idle_timeout_session.cr │ ├── login_params.cr │ ├── login_session.cr │ ├── mixins │ │ ├── basic_credentials.cr │ │ ├── bearer_credentials.cr │ │ ├── bearer_login_verifier.cr │ │ ├── credentials.cr │ │ ├── email_confirmation_verifier.cr │ │ ├── hash.cr │ │ ├── login_verifier.cr │ │ ├── oauth_access_token_credentials.cr │ │ ├── oauth_access_token_verifier.cr │ │ ├── oauth_client_verifier.cr │ │ ├── oauth_grant_verifier.cr │ │ ├── param_credentials.cr │ │ ├── password_reset_verifier.cr │ │ └── verifier.cr │ ├── oauth_client_credentials.cr │ ├── oauth_client_headers.cr │ ├── oauth_client_params.cr │ ├── oauth_client_session.cr │ ├── oauth_grant_credentials.cr │ ├── oauth_grant_params.cr │ ├── oauth_grant_pkce.cr │ ├── oauth_response_type.cr │ ├── oauth_state_session.cr │ ├── page_url_session.cr │ ├── password_authentication.cr │ ├── password_reset_credentials.cr │ ├── password_reset_params.cr │ ├── password_reset_session.cr │ ├── return_url_session.cr │ └── sha256_hash.cr └── version.cr └── spec.cr /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 2 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.shards/ 2 | /.vscode/ 3 | /bin/ 4 | /lib/ 5 | /tmp/ 6 | *.dwarf 7 | .env* 8 | /.*-version* 9 | /shard.lock 10 | -------------------------------------------------------------------------------- /shard.edge.yml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | avram: 3 | github: luckyframework/avram 4 | branch: main 5 | carbon: 6 | github: luckyframework/carbon 7 | branch: main 8 | lucky: 9 | github: luckyframework/lucky 10 | branch: main 11 | lucky_env: 12 | github: luckyframework/lucky_env 13 | branch: main 14 | -------------------------------------------------------------------------------- /shard.latest.yml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | avram: 3 | github: luckyframework/avram 4 | version: ~> 1.4 5 | carbon: 6 | github: luckyframework/carbon 7 | version: ~> 0.6.0 8 | lucky: 9 | github: luckyframework/lucky 10 | version: ~> 1.4 11 | lucky_env: 12 | github: luckyframework/lucky_env 13 | version: ~> 0.3.0 14 | -------------------------------------------------------------------------------- /spec/setup/database.cr: -------------------------------------------------------------------------------- 1 | unless Bool.adapter.parse(ENV["SKIP_CREATE_DB"]?.to_s).value 2 | Db::Create.new(quiet: true).call 3 | end 4 | 5 | Db::Migrate.new(quiet: true).call 6 | 7 | Avram::SpecHelper.use_transactional_specs(Avram.settings.database_to_migrate) 8 | -------------------------------------------------------------------------------- /spec/setup/email.cr: -------------------------------------------------------------------------------- 1 | Spec.before_each do 2 | Carbon::DevAdapter.reset 3 | end 4 | -------------------------------------------------------------------------------- /spec/setup/server.cr: -------------------------------------------------------------------------------- 1 | app_server = AppServer.new 2 | 3 | spawn do 4 | app_server.listen 5 | end 6 | 7 | Spec.after_suite do 8 | app_server.close 9 | end 10 | -------------------------------------------------------------------------------- /spec/setup/webmock.cr: -------------------------------------------------------------------------------- 1 | Spec.before_each do 2 | WebMock.reset 3 | WebMock.allow_net_connect = true 4 | end 5 | -------------------------------------------------------------------------------- /spec/shield/actions/oauth/authorize_spec.cr: -------------------------------------------------------------------------------- 1 | require "../../../spec_helper" 2 | 3 | describe Shield::Oauth::Authorize do 4 | it "redirects request" do 5 | response = ApiClient.exec(Oauth::Authorize) 6 | 7 | response.status.should eq(HTTP::Status::FOUND) 8 | response.headers["Location"]?.should(eq Oauth::Authorization::New.path) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/shield/operations/delete_user_spec.cr: -------------------------------------------------------------------------------- 1 | require "../../spec_helper" 2 | 3 | describe Shield::DeleteUser do 4 | it "does not delete current user" do 5 | user = UserFactory.create 6 | 7 | DeleteUser.delete(user, current_user: user) do |operation, _| 8 | operation.deleted?.should be_false 9 | operation.id.should have_error("operation.error.self_delete_forbidden") 10 | 11 | # ameba:disable Performance/AnyInsteadOfEmpty 12 | UserQuery.new.id(user.id).any?.should be_true 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/shield/operations/revoke_bearer_login_spec.cr: -------------------------------------------------------------------------------- 1 | require "../../spec_helper" 2 | 3 | describe Shield::RevokeBearerLogin do 4 | it "ends bearer login" do 5 | bearer_login = BearerLoginFactory.create &.user_id(UserFactory.create.id) 6 | 7 | bearer_login.status.active?.should be_true 8 | 9 | RevokeBearerLogin.update(bearer_login) do |operation, updated_bearer_login| 10 | operation.saved?.should be_true 11 | 12 | updated_bearer_login.status.active?.should be_false 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/shield/operations/update_password_spec.cr: -------------------------------------------------------------------------------- 1 | require "../../spec_helper" 2 | 3 | describe Shield::UpdatePassword do 4 | it "requires password" do 5 | user = UserFactory.create 6 | 7 | UpdatePassword.update(user, current_login: nil) do |operation, _| 8 | operation.saved?.should be_false 9 | 10 | operation.password.should have_error("operation.error.password_required") 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/spec_helper.cr: -------------------------------------------------------------------------------- 1 | ENV["LUCKY_ENV"] = "test" 2 | 3 | require "spec" 4 | require "webmock" 5 | 6 | require "./support/boot" 7 | require "./setup/**" 8 | 9 | require "../src/spec" 10 | 11 | Habitat.raise_if_missing_settings! 12 | 13 | Avram::Migrator::Runner.new.ensure_migrated! 14 | Avram::SchemaEnforcer.ensure_correct_column_mappings! 15 | 16 | include Carbon::Expectations 17 | include Lucky::RequestExpectations 18 | -------------------------------------------------------------------------------- /spec/support/api_client.cr: -------------------------------------------------------------------------------- 1 | class ApiClient < Lucky::BaseHTTPClient 2 | def initialize 3 | super 4 | headers("Content-Type": "application/json") 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /spec/support/app/config/cookies.cr: -------------------------------------------------------------------------------- 1 | require "./server" 2 | 3 | Lucky::Session.configure do |settings| 4 | settings.key = "_shield_spec_session" 5 | end 6 | 7 | Lucky::CookieJar.configure do |settings| 8 | settings.on_set = ->(cookie : HTTP::Cookie) do 9 | cookie.secure(Lucky::ForceSSLHandler.settings.enabled) 10 | cookie.http_only(true) 11 | cookie.path("/") 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/support/app/config/database.cr: -------------------------------------------------------------------------------- 1 | AppDatabase.configure do |settings| 2 | settings.credentials = Avram::Credentials.parse(ENV["DATABASE_URL"]) 3 | end 4 | 5 | Avram.configure do |settings| 6 | settings.database_to_migrate = AppDatabase 7 | settings.lazy_load_enabled = LuckyEnv.production? 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/config/email.cr: -------------------------------------------------------------------------------- 1 | BaseEmail.configure do |settings| 2 | settings.adapter = Carbon::DevAdapter.new 3 | settings.deliver_later_strategy = DevDeliverLaterStrategy.new 4 | end 5 | -------------------------------------------------------------------------------- /spec/support/app/config/env.cr: -------------------------------------------------------------------------------- 1 | unless Bool.adapter.parse(ENV["SKIP_LOAD_ENV"]?.to_s).value 2 | LuckyEnv.load(".env") 3 | end 4 | -------------------------------------------------------------------------------- /spec/support/app/config/error_handler.cr: -------------------------------------------------------------------------------- 1 | Lucky::ErrorHandler.configure do |settings| 2 | settings.show_debug_output = !LuckyEnv.production? 3 | end 4 | -------------------------------------------------------------------------------- /spec/support/app/config/i18n.cr: -------------------------------------------------------------------------------- 1 | Rex.configure do |settings| 2 | settings.adapter = Rex::DevAdapter.new 3 | end 4 | -------------------------------------------------------------------------------- /spec/support/app/config/route_helper.cr: -------------------------------------------------------------------------------- 1 | Lucky::RouteHelper.configure do |settings| 2 | settings.base_uri = "http://localhost:5000" 3 | end 4 | -------------------------------------------------------------------------------- /spec/support/app/config/server.cr: -------------------------------------------------------------------------------- 1 | Lucky::Server.configure do |settings| 2 | settings.secret_key_base = "abcdefghijklmnopqrstuvwxyz123456" 3 | settings.host = "0.0.0.0" 4 | settings.port = 5000 5 | settings.gzip_enabled = false 6 | end 7 | 8 | Lucky::ForceSSLHandler.configure do |settings| 9 | settings.enabled = false 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/config/shield.cr: -------------------------------------------------------------------------------- 1 | Shield.configure do |settings| 2 | settings.oauth_access_token_scopes_allowed = 3 | BearerScope.action_scopes.map(&.to_s) 4 | 5 | settings.bearer_login_scopes_allowed = BearerScope.action_scopes.map(&.to_s) 6 | settings.oauth_client_name_filter = /^grotto.*$/i 7 | settings.oauth_code_challenge_methods_allowed = ["plain", "S256"] 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/db/migrations/20230119160301_create_users.cr: -------------------------------------------------------------------------------- 1 | class CreateUsers::V20230119160301 < Avram::Migrator::Migration::V1 2 | def migrate 3 | create :users do 4 | primary_key id : Int64 5 | 6 | add_timestamps 7 | 8 | add email : String, unique: true 9 | add level : String 10 | add password_digest : String 11 | end 12 | end 13 | 14 | def rollback 15 | drop :users 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/support/app/db/migrations/20230119160524_create_logins.cr: -------------------------------------------------------------------------------- 1 | class CreateLogins::V20230119160424 < Avram::Migrator::Migration::V1 2 | def migrate 3 | create :logins do 4 | primary_key id : Int64 5 | 6 | add_timestamps 7 | 8 | add_belongs_to user : User, on_delete: :cascade 9 | 10 | add active_at : Time 11 | add inactive_at : Time? 12 | add ip_address : String 13 | add token_digest : String 14 | end 15 | end 16 | 17 | def rollback 18 | drop :logins 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/support/app/db/migrations/20230119161548_add_bearer_logins_oauth_client_id.cr: -------------------------------------------------------------------------------- 1 | class AddBearerLoginsOauthClientId::V20230119161548 < 2 | Avram::Migrator::Migration::V1 3 | 4 | def migrate 5 | alter :bearer_logins do 6 | add_belongs_to oauth_client : OauthClient?, 7 | foreign_key_type: UUID, 8 | on_delete: :cascade 9 | end 10 | end 11 | 12 | def rollback 13 | alter :bearer_logins do 14 | remove_belongs_to :oauth_client 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/about/create.cr: -------------------------------------------------------------------------------- 1 | class About::Create < BrowserAction 2 | skip :require_logged_in 3 | skip :require_logged_out 4 | 5 | post "/about" do 6 | redirect_back fallback: Home::Show 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/about/index.cr: -------------------------------------------------------------------------------- 1 | class About::Index < BrowserAction 2 | skip :require_logged_in 3 | skip :require_logged_out 4 | 5 | get "/about" do 6 | json({page: "About::Index", previous_page: previous_page_url?}) 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/about/new.cr: -------------------------------------------------------------------------------- 1 | class About::New < BrowserAction 2 | get "/about/new" do 3 | json({page: "About::New", session: LoginSession.new(session).login_id?}) 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/about/update.cr: -------------------------------------------------------------------------------- 1 | class About::Update < BrowserAction 2 | skip :require_logged_in 3 | skip :require_logged_out 4 | 5 | put "/about" do 6 | redirect_back fallback: Home::Show 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/bearer_logins/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::BearerLogins::Delete < ApiAction 2 | include Shield::Api::BearerLogins::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/bearer-logins/delete/:bearer_login_id" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/bearer_logins/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::BearerLogins::Destroy < ApiAction 2 | include Shield::Api::BearerLogins::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/bearer-logins/:bearer_login_id" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/bearer_logins/index.cr: -------------------------------------------------------------------------------- 1 | class Api::BearerLogins::Index < ApiAction 2 | include Shield::Api::BearerLogins::Index 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | param page : Int32 = 1 8 | 9 | get "/bearer-logins" do 10 | json BearerLoginSerializer.new(bearer_logins: bearer_logins, pages: pages) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/bearer_logins/show.cr: -------------------------------------------------------------------------------- 1 | class Api::BearerLogins::Show < ApiAction 2 | include Shield::Api::BearerLogins::Show 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | get "/bearer-logins/:bearer_login_id" do 8 | json BearerLoginSerializer.new(bearer_login: bearer_login) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/bearer_logins/token/verify.cr: -------------------------------------------------------------------------------- 1 | class Api::BearerLogins::Token::Verify < ApiAction 2 | include Shield::Api::BearerLogins::Token::Verify 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | post "/bearer-logins/token/verify" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/bearer_logins/update.cr: -------------------------------------------------------------------------------- 1 | class Api::BearerLogins::Update < ApiAction 2 | include Shield::Api::BearerLogins::Update 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | patch "/bearer-logins/:bearer_login_id" do 8 | run_operation 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_login/create.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentLogin::Create < ApiAction 2 | include Shield::Api::CurrentLogin::Create 3 | include Shield::Api::SkipAuthenticationCache 4 | 5 | post "/log-in" do 6 | run_operation 7 | end 8 | 9 | def remote_ip? : Socket::IPAddress? 10 | Socket::IPAddress.new("128.0.0.2", 5000) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_login/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentLogin::Delete < ApiAction 2 | include Shield::Api::CurrentLogin::Delete 3 | 4 | delete "/login/delete" do 5 | run_operation 6 | end 7 | 8 | def remote_ip? : Socket::IPAddress? 9 | Socket::IPAddress.new("128.0.0.2", 5000) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_login/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentLogin::Destroy < ApiAction 2 | include Shield::Api::CurrentLogin::Destroy 3 | 4 | delete "/log-in" do 5 | run_operation 6 | end 7 | 8 | def remote_ip? : Socket::IPAddress? 9 | Socket::IPAddress.new("128.0.0.2", 5000) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/bearer_logins/create.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::BearerLogins::Create < ApiAction 2 | include Shield::Api::CurrentUser::BearerLogins::Create 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | post "/account/bearer-logins" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/bearer_logins/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::BearerLogins::Delete < ApiAction 2 | include Shield::Api::CurrentUser::BearerLogins::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/bearer-logins/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/bearer_logins/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::BearerLogins::Destroy < ApiAction 2 | include Shield::Api::CurrentUser::BearerLogins::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/bearer-logins" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/bearer_logins/index.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::BearerLogins::Index < ApiAction 2 | include Shield::Api::CurrentUser::BearerLogins::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/account/bearer-logins" do 9 | json BearerLoginSerializer.new(bearer_logins: bearer_logins, pages: pages) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/create.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::Create < ApiAction 2 | include Shield::Api::EmailConfirmationCurrentUser::Create 3 | 4 | post "/ec" do 5 | run_operation 6 | end 7 | 8 | def remote_ip? : Socket::IPAddress? 9 | Socket::IPAddress.new("128.0.0.2", 5000) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/email_confirmations/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::EmailConfirmations::Delete < ApiAction 2 | include Shield::Api::CurrentUser::EmailConfirmations::Delete 3 | 4 | delete "/account/email-confirmations/delete" do 5 | run_operation 6 | end 7 | 8 | def remote_ip? : Socket::IPAddress? 9 | Socket::IPAddress.new("128.0.0.2", 5000) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/email_confirmations/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::EmailConfirmations::Destroy < ApiAction 2 | include Shield::Api::CurrentUser::EmailConfirmations::Destroy 3 | 4 | delete "/account/email-confirmations" do 5 | run_operation 6 | end 7 | 8 | def remote_ip? : Socket::IPAddress? 9 | Socket::IPAddress.new("128.0.0.2", 5000) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/email_confirmations/index.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::EmailConfirmations::Index < ApiAction 2 | include Shield::Api::CurrentUser::EmailConfirmations::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/account/email-confirmations" do 9 | json EmailConfirmationSerializer.new( 10 | email_confirmations: email_confirmations, 11 | pages: pages 12 | ) 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/logins/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::Logins::Delete < ApiAction 2 | include Shield::Api::CurrentUser::Logins::Delete 3 | 4 | delete "/account/logins/delete" do 5 | run_operation 6 | end 7 | 8 | def remote_ip? : Socket::IPAddress? 9 | Socket::IPAddress.new("128.0.0.2", 5000) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/logins/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::Logins::Destroy < ApiAction 2 | include Shield::Api::CurrentUser::Logins::Destroy 3 | 4 | delete "/account/logins" do 5 | run_operation 6 | end 7 | 8 | def remote_ip? : Socket::IPAddress? 9 | Socket::IPAddress.new("128.0.0.2", 5000) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/logins/index.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::Logins::Index < ApiAction 2 | include Shield::Api::CurrentUser::Logins::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/account/logins" do 9 | json LoginSerializer.new(logins: logins, pages: pages) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/oauth_access_tokens/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::OauthAccessTokens::Delete < ApiAction 2 | include Shield::Api::CurrentUser::OauthAccessTokens::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/oauth/tokens/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/oauth_access_tokens/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::OauthAccessTokens::Destroy < ApiAction 2 | include Shield::Api::CurrentUser::OauthAccessTokens::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/oauth/tokens" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/oauth_access_tokens/index.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::OauthAccessTokens::Index < ApiAction 2 | include Shield::Api::CurrentUser::OauthAccessTokens::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/account/oauth/tokens" do 9 | json BearerLoginSerializer.new(bearer_logins: bearer_logins, pages: pages) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/oauth_clients/create.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::OauthClients::Create < ApiAction 2 | include Shield::Api::CurrentUser::OauthClients::Create 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | post "/account/oauth/clients" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/oauth_clients/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::OauthClients::Delete < ApiAction 2 | include Shield::Api::CurrentUser::OauthClients::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/oauth/clients/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/oauth_clients/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::OauthClients::Destroy < ApiAction 2 | include Shield::Api::CurrentUser::OauthClients::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/oauth/clients" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/oauth_clients/index.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::OauthClients::Index < ApiAction 2 | include Shield::Api::CurrentUser::OauthClients::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/account/oauth/clients" do 9 | json OauthClientSerializer.new(oauth_clients: oauth_clients, pages: pages) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/oauth_grants/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::OauthGrants::Delete < ApiAction 2 | include Shield::Api::CurrentUser::OauthGrants::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/oauth/grants/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/oauth_grants/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::OauthGrants::Destroy < ApiAction 2 | include Shield::Api::CurrentUser::OauthGrants::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/oauth/grants" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/oauth_grants/index.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::OauthGrants::Index < ApiAction 2 | include Shield::Api::CurrentUser::OauthGrants::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/account/oauth/grants" do 9 | json OauthGrantSerializer.new(oauth_grants: oauth_grants, pages: pages) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/oauth_permissions/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::OauthPermissions::Delete < ApiAction 2 | include Shield::Api::CurrentUser::OauthPermissions::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/oauth/permissions/:oauth_client_id/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/oauth_permissions/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::OauthPermissions::Destroy < ApiAction 2 | include Shield::Api::CurrentUser::OauthPermissions::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/accounts/oauth/permissions/:oauth_client_id" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/oauth_permissions/index.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::OauthPermissions::Index < ApiAction 2 | include Shield::Api::CurrentUser::OauthPermissions::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/account/oauth/permissions" do 9 | json OauthClientSerializer.new(oauth_clients: oauth_clients, pages: pages) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/password_resets/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::PasswordResets::Delete < ApiAction 2 | include Shield::Api::CurrentUser::PasswordResets::Delete 3 | 4 | delete "/account/password-resets/delete" do 5 | run_operation 6 | end 7 | 8 | def remote_ip? : Socket::IPAddress? 9 | Socket::IPAddress.new("128.0.0.2", 5000) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/password_resets/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::PasswordResets::Destroy < ApiAction 2 | include Shield::Api::CurrentUser::PasswordResets::Destroy 3 | 4 | delete "/account/password-resets" do 5 | run_operation 6 | end 7 | 8 | def remote_ip? : Socket::IPAddress? 9 | Socket::IPAddress.new("128.0.0.2", 5000) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/password_resets/index.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::PasswordResets::Index < ApiAction 2 | include Shield::Api::CurrentUser::PasswordResets::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/account/password-resets" do 9 | json PasswordResetSerializer.new( 10 | password_resets: password_resets, 11 | pages: pages 12 | ) 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/show.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::Show < ApiAction 2 | include Shield::Api::EmailConfirmationCurrentUser::Show 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | get "/ec/profile" do 7 | json UserSerializer.new(user: user) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/current_user/update.cr: -------------------------------------------------------------------------------- 1 | class Api::CurrentUser::Update < ApiAction 2 | include Shield::Api::EmailConfirmationCurrentUser::Update 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | patch "/ec/profile" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/email_confirmations/create.cr: -------------------------------------------------------------------------------- 1 | class Api::EmailConfirmations::Create < ApiAction 2 | include Shield::Api::EmailConfirmations::Create 3 | 4 | post "/email-confirmations" do 5 | run_operation 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/email_confirmations/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::EmailConfirmations::Delete < ApiAction 2 | include Shield::Api::EmailConfirmations::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/email-confirmations/:email_confirmation_id/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/email_confirmations/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::EmailConfirmations::Destroy < ApiAction 2 | include Shield::Api::EmailConfirmations::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/email-confirmations/:email_confirmation_id" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/email_confirmations/index.cr: -------------------------------------------------------------------------------- 1 | class Api::EmailConfirmations::Index < ApiAction 2 | include Shield::Api::EmailConfirmations::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/email-confirmations" do 9 | json EmailConfirmationSerializer.new( 10 | email_confirmations: email_confirmations, 11 | pages: pages 12 | ) 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/email_confirmations/show.cr: -------------------------------------------------------------------------------- 1 | class Api::EmailConfirmations::Show < ApiAction 2 | include Shield::Api::EmailConfirmations::Show 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | get "/email-confirmations/:email_confirmation_id" do 7 | json EmailConfirmationSerializer.new(email_confirmation: email_confirmation) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/email_confirmations/token/verify.cr: -------------------------------------------------------------------------------- 1 | class Api::EmailConfirmations::Token::Verify < ApiAction 2 | include Shield::Api::EmailConfirmations::Token::Verify 3 | 4 | skip :pin_login_to_ip_address 5 | skip :pin_email_confirmation_to_ip_address 6 | 7 | post "/email-confirmations/token/verify" do 8 | run_operation 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/email_confirmations/update.cr: -------------------------------------------------------------------------------- 1 | class Api::EmailConfirmations::Update < ApiAction 2 | include Shield::Api::EmailConfirmations::Update 3 | 4 | skip :pin_login_to_ip_address 5 | skip :pin_email_confirmation_to_ip_address 6 | 7 | patch "/email-confirmations" do 8 | run_operation 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/logins/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::Logins::Delete < ApiAction 2 | include Shield::Api::Logins::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/logins/delete/:login_id" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/logins/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::Logins::Destroy < ApiAction 2 | include Shield::Api::Logins::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/logins/:login_id" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/logins/index.cr: -------------------------------------------------------------------------------- 1 | class Api::Logins::Index < ApiAction 2 | include Shield::Api::Logins::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/logins" do 9 | json LoginSerializer.new(logins: logins, pages: pages) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/logins/show.cr: -------------------------------------------------------------------------------- 1 | class Api::Logins::Show < ApiAction 2 | include Shield::Api::Logins::Show 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | get "/logins/:login_id" do 8 | json LoginSerializer.new(login: login) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/logins/token/verify.cr: -------------------------------------------------------------------------------- 1 | class Api::Logins::Token::Verify < ApiAction 2 | include Shield::Api::Logins::Token::Verify 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | post "/logins/token/verify" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/oauth/token/create.cr: -------------------------------------------------------------------------------- 1 | class Api::Oauth::Token::Create < ApiAction 2 | include Shield::Api::Oauth::Token::Create 3 | 4 | post "/oauth/token" do 5 | run_operation 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/oauth/token/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::Oauth::Token::Delete < ApiAction 2 | include Shield::Api::Oauth::Token::Delete 3 | 4 | post "/oauth/token/delete" do 5 | run_operation 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/oauth/token/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::Oauth::Token::Destroy < ApiAction 2 | include Shield::Api::Oauth::Token::Destroy 3 | 4 | post "/oauth/token/revoke" do 5 | run_operation 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/oauth/token/verify.cr: -------------------------------------------------------------------------------- 1 | class Api::Oauth::Token::Verify < ApiAction 2 | include Shield::Api::Oauth::Token::Verify 3 | 4 | post "/oauth/token/verify" do 5 | run_operation 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/oauth_access_tokens/index.cr: -------------------------------------------------------------------------------- 1 | class Api::OauthAccessTokens::Index < ApiAction 2 | include Shield::Api::OauthAccessTokens::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/oauth/tokens" do 9 | json BearerLoginSerializer.new(bearer_logins: bearer_logins, pages: pages) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/oauth_clients/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::OauthClients::Delete < ApiAction 2 | include Shield::Api::OauthClients::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/oauth/clients/:oauth_client_id/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/oauth_clients/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::OauthClients::Destroy < ApiAction 2 | include Shield::Api::OauthClients::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/oauth/clients/:oauth_client_id" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/oauth_clients/index.cr: -------------------------------------------------------------------------------- 1 | class Api::OauthClients::Index < ApiAction 2 | include Shield::Api::OauthClients::Index 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | param page : Int32 = 1 8 | 9 | get "/oauth/clients" do 10 | json OauthClientSerializer.new(oauth_clients: oauth_clients, pages: pages) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/oauth_clients/secret/update.cr: -------------------------------------------------------------------------------- 1 | class Api::OauthClients::Secret::Update < ApiAction 2 | include Shield::Api::OauthClients::Secret::Update 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | patch "/oauth/clients/:oauth_client_id/secret" do 8 | run_operation 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/oauth_clients/show.cr: -------------------------------------------------------------------------------- 1 | class Api::OauthClients::Show < ApiAction 2 | include Shield::Api::OauthClients::Show 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | get "/oauth/clients/:oauth_client_id" do 8 | json OauthClientSerializer.new(oauth_client: oauth_client) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/oauth_clients/update.cr: -------------------------------------------------------------------------------- 1 | class Api::OauthClients::Update < ApiAction 2 | include Shield::Api::OauthClients::Update 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | patch "/oauth/clients/:oauth_client_id" do 8 | run_operation 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/oauth_clients/users/index.cr: -------------------------------------------------------------------------------- 1 | class Api::OauthClients::Users::Index < ApiAction 2 | include Shield::Api::OauthClients::Users::Index 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | param page : Int32 = 1 8 | 9 | get "/oauth/clients/:oauth_client_id/users" do 10 | json UserSerializer.new( 11 | users: users, 12 | oauth_client: oauth_client, 13 | pages: pages 14 | ) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/oauth_grants/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::OauthGrants::Delete < ApiAction 2 | include Shield::Api::OauthGrants::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/oauth/grants/:oauth_grant_id/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/oauth_grants/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::OauthGrants::Destroy < ApiAction 2 | include Shield::Api::OauthGrants::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/oauth/grants/:oauth_grant_id" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/oauth_grants/index.cr: -------------------------------------------------------------------------------- 1 | class Api::OauthGrants::Index < ApiAction 2 | include Shield::Api::OauthGrants::Index 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | param page : Int32 = 1 8 | 9 | get "/oauth/grants" do 10 | json OauthGrantSerializer.new(oauth_grants: oauth_grants, pages: pages) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/oauth_grants/show.cr: -------------------------------------------------------------------------------- 1 | class Api::OauthGrants::Show < ApiAction 2 | include Shield::Api::OauthGrants::Show 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | get "/oauth/grants/:oauth_grant_id" do 8 | json OauthGrantSerializer.new(oauth_grant: oauth_grant) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/password_resets/create.cr: -------------------------------------------------------------------------------- 1 | class Api::PasswordResets::Create < ApiAction 2 | include Shield::Api::PasswordResets::Create 3 | 4 | post "/password-resets" do 5 | run_operation 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/password_resets/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::PasswordResets::Delete < ApiAction 2 | include Shield::Api::PasswordResets::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/password-resets/:password_reset_id/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/password_resets/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::PasswordResets::Destroy < ApiAction 2 | include Shield::Api::PasswordResets::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/password-resets/:password_reset_id" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/password_resets/index.cr: -------------------------------------------------------------------------------- 1 | class Api::PasswordResets::Index < ApiAction 2 | include Shield::Api::PasswordResets::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/password-resets" do 9 | json PasswordResetSerializer.new( 10 | password_resets: password_resets, 11 | pages: pages 12 | ) 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/password_resets/show.cr: -------------------------------------------------------------------------------- 1 | class Api::PasswordResets::Show < ApiAction 2 | include Shield::Api::PasswordResets::Show 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | get "/password-resets/:password_reset_id" do 7 | json PasswordResetSerializer.new(password_reset: password_reset) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/password_resets/token/verify.cr: -------------------------------------------------------------------------------- 1 | class Api::PasswordResets::Token::Verify < ApiAction 2 | include Shield::Api::PasswordResets::Token::Verify 3 | 4 | skip :pin_login_to_ip_address 5 | skip :pin_password_reset_to_ip_address 6 | 7 | post "/password-resets/token/verify" do 8 | run_operation 9 | end 10 | 11 | def remote_ip? : Socket::IPAddress? 12 | Socket::IPAddress.new("128.0.0.2", 5000) 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/password_resets/update.cr: -------------------------------------------------------------------------------- 1 | class Api::PasswordResets::Update < ApiAction 2 | include Shield::Api::PasswordResets::Update 3 | 4 | patch "/password-resets" do 5 | run_operation 6 | end 7 | 8 | def remote_ip? : Socket::IPAddress? 9 | Socket::IPAddress.new("128.0.0.2", 5000) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/posts/create.cr: -------------------------------------------------------------------------------- 1 | class Api::Posts::Create < ApiAction 2 | skip :require_logged_out 3 | skip :pin_login_to_ip_address 4 | 5 | post "/posts" do 6 | json({ 7 | scopes: current_bearer_login?.try &.scopes, 8 | current_bearer: current_bearer?.try &.id, 9 | current_user: current_user?.try &.id 10 | }) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/posts/index.cr: -------------------------------------------------------------------------------- 1 | class Api::Posts::Index < ApiAction 2 | skip :require_logged_out 3 | 4 | get "/posts" do 5 | json({ 6 | scopes: current_bearer_login?.try &.scopes, 7 | current_bearer: current_bearer?.try &.id, 8 | current_user: current_user?.try &.id 9 | }) 10 | end 11 | 12 | def authorize?(user : User) : Bool 13 | true 14 | end 15 | 16 | def remote_ip? : Socket::IPAddress? 17 | Socket::IPAddress.new("128.0.0.2", 5000) 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/posts/new.cr: -------------------------------------------------------------------------------- 1 | class Api::Posts::New < ApiAction 2 | skip :require_logged_in 3 | 4 | get "/posts/new" do 5 | json({ 6 | scopes: current_bearer_login?.try &.scopes, 7 | current_bearer: current_bearer?.try &.id, 8 | current_user: current_user?.try &.id 9 | }) 10 | end 11 | 12 | def authorize?(user : User) : Bool 13 | true 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/regular_current_user/show.cr: -------------------------------------------------------------------------------- 1 | class Api::RegularCurrentUser::Show < ApiAction 2 | include Shield::Api::CurrentUser::Show 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | get "/profile" do 7 | json UserSerializer.new(user: user) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/bearer_logins/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::BearerLogins::Delete < ApiAction 2 | include Shield::Api::Users::BearerLogins::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/bearer-logins/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/bearer_logins/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::BearerLogins::Destroy < ApiAction 2 | include Shield::Api::Users::BearerLogins::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/bearer-logins" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/bearer_logins/index.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::BearerLogins::Index < ApiAction 2 | include Shield::Api::Users::BearerLogins::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/users/:user_id/bearer-logins" do 9 | json BearerLoginSerializer.new( 10 | bearer_logins: bearer_logins, 11 | user: user, 12 | pages: pages 13 | ) 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/create.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::Create < ApiAction 2 | include Shield::Api::Users::Create 3 | 4 | skip :pin_login_to_ip_address 5 | skip :check_authorization 6 | 7 | post "/users" do 8 | run_operation 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::Delete < ApiAction 2 | include Shield::Api::Users::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | skip :check_authorization 6 | 7 | delete "/users/:user_id" do 8 | run_operation 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/email_confirmations/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::EmailConfirmations::Delete < ApiAction 2 | include Shield::Api::Users::EmailConfirmations::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/email-confirmations/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/email_confirmations/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::EmailConfirmations::Destroy < ApiAction 2 | include Shield::Api::Users::EmailConfirmations::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/email-confirmations" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/email_confirmations/index.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::EmailConfirmations::Index < ApiAction 2 | include Shield::Api::Users::EmailConfirmations::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/users/:user_id/email-confirmations" do 9 | json EmailConfirmationSerializer.new( 10 | email_confirmations: email_confirmations, 11 | user: user, 12 | pages: pages 13 | ) 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/index.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::Index < ApiAction 2 | include Shield::Api::Users::Index 3 | 4 | skip :pin_login_to_ip_address 5 | skip :check_authorization 6 | 7 | param page : Int32 = 1 8 | 9 | get "/users" do 10 | json UserSerializer.new(users: users, pages: pages) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/logins/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::Logins::Delete < ApiAction 2 | include Shield::Api::Users::Logins::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/logins/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/logins/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::Logins::Destroy < ApiAction 2 | include Shield::Api::Users::Logins::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/logins" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/logins/index.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::Logins::Index < ApiAction 2 | include Shield::Api::Users::Logins::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/users/:user_id/logins" do 9 | json LoginSerializer.new(logins: logins, user: user, pages: pages) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/oauth_access_tokens/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::OauthAccessTokens::Delete < ApiAction 2 | include Shield::Api::Users::OauthAccessTokens::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/oauth/tokens/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/oauth_access_tokens/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::OauthAccessTokens::Destroy < ApiAction 2 | include Shield::Api::Users::OauthAccessTokens::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/oauth/tokens" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/oauth_access_tokens/index.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::OauthAccessTokens::Index < ApiAction 2 | include Shield::Api::Users::OauthAccessTokens::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/users/:user_id/oauth/tokens" do 9 | json BearerLoginSerializer.new( 10 | bearer_logins: bearer_logins, 11 | user: user, 12 | pages: pages 13 | ) 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/oauth_clients/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::OauthClients::Delete < ApiAction 2 | include Shield::Api::Users::OauthClients::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/oauth/clients/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/oauth_clients/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::OauthClients::Destroy < ApiAction 2 | include Shield::Api::Users::OauthClients::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/oauth/clients" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/oauth_clients/index.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::OauthClients::Index < ApiAction 2 | include Shield::Api::Users::OauthClients::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/users/:user_id/oauth/clients" do 9 | json OauthClientSerializer.new( 10 | oauth_clients: oauth_clients, 11 | user: user, 12 | pages: pages 13 | ) 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/oauth_grants/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::OauthGrants::Delete < ApiAction 2 | include Shield::Api::Users::OauthGrants::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/oauth/grants/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/oauth_grants/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::OauthGrants::Destroy < ApiAction 2 | include Shield::Api::Users::OauthGrants::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/oauth/grants" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/oauth_grants/index.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::OauthGrants::Index < ApiAction 2 | include Shield::Api::Users::OauthGrants::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/users/:user_id/oauth/grants" do 9 | json OauthGrantSerializer.new( 10 | oauth_grants: oauth_grants, 11 | user: user, 12 | pages: pages 13 | ) 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/oauth_permissions/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::OauthPermissions::Delete < ApiAction 2 | include Shield::Api::Users::OauthPermissions::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/oauth/permissions/:oauth_client_id/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/oauth_permissions/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::OauthPermissions::Destroy < ApiAction 2 | include Shield::Api::Users::OauthPermissions::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/oauth/permissions/:oauth_client_id" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/oauth_permissions/index.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::OauthPermissions::Index < ApiAction 2 | include Shield::Api::Users::OauthPermissions::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/users/:user_id/oauth/permissions" do 9 | json OauthClientSerializer.new( 10 | oauth_clients: oauth_clients, 11 | user: user, 12 | pages: pages 13 | ) 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/password_resets/delete.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::PasswordResets::Delete < ApiAction 2 | include Shield::Api::Users::PasswordResets::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/password-resets/delete" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/password_resets/destroy.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::PasswordResets::Destroy < ApiAction 2 | include Shield::Api::Users::PasswordResets::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/password-resets" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/password_resets/index.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::PasswordResets::Index < ApiAction 2 | include Shield::Api::Users::PasswordResets::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/users/:user_id/password-resets" do 9 | json PasswordResetSerializer.new( 10 | password_resets: password_resets, 11 | user: user, 12 | pages: pages 13 | ) 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/show.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::Show < ApiAction 2 | include Shield::Api::Users::Show 3 | 4 | skip :pin_login_to_ip_address 5 | skip :check_authorization 6 | 7 | get "/users/:user_id" do 8 | json UserSerializer.new(user: user) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/api/users/update.cr: -------------------------------------------------------------------------------- 1 | class Api::Users::Update < ApiAction 2 | include Shield::Api::Users::Update 3 | 4 | skip :pin_login_to_ip_address 5 | skip :check_authorization 6 | 7 | patch "/users/:user_id" do 8 | run_operation 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/bearer_logins/delete.cr: -------------------------------------------------------------------------------- 1 | class BearerLogins::Delete < BrowserAction 2 | include Shield::BearerLogins::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/bearer-logins/delete/:bearer_login_id" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, bearer_login) 11 | response.headers["X-Bearer-Login-ID"] = bearer_login.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/bearer_logins/destroy.cr: -------------------------------------------------------------------------------- 1 | class BearerLogins::Destroy < BrowserAction 2 | include Shield::BearerLogins::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/bearer-logins/:bearer_login_id" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, bearer_login) 11 | response.headers["X-Bearer-Login-ID"] = bearer_login.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/bearer_logins/edit.cr: -------------------------------------------------------------------------------- 1 | class BearerLogins::Edit < BrowserAction 2 | include Shield::BearerLogins::Edit 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | get "/bearer-logins/:bearer_login_id/edit" do 8 | operation = UpdateBearerLogin.new(bearer_login) 9 | html EditPage, operation: operation 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/bearer_logins/index.cr: -------------------------------------------------------------------------------- 1 | class BearerLogins::Index < BrowserAction 2 | include Shield::BearerLogins::Index 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | param page : Int32 = 1 8 | 9 | get "/bearer-logins" do 10 | html IndexPage, bearer_logins: bearer_logins, pages: pages 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/bearer_logins/show.cr: -------------------------------------------------------------------------------- 1 | class BearerLogins::Show < BrowserAction 2 | include Shield::BearerLogins::Show 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | get "/bearer-logins/:bearer_login_id" do 8 | html ShowPage, bearer_login: bearer_login 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/bearer_logins/token/show.cr: -------------------------------------------------------------------------------- 1 | class BearerLogins::Token::Show < BrowserAction 2 | include Shield::BearerLogins::Token::Show 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | get "/bearer-logins/token" do 8 | html ShowPage, bearer_login: bearer_login?, token: token? 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/bearer_logins/update.cr: -------------------------------------------------------------------------------- 1 | class BearerLogins::Update < BrowserAction 2 | include Shield::BearerLogins::Update 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | patch "/bearer-logins/:bearer_login_id" do 8 | run_operation 9 | end 10 | 11 | def do_run_operation_succeeded(operation, bearer_login) 12 | response.headers["X-Bearer-Login-ID"] = bearer_login.id.to_s 13 | previous_def 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_login/delete.cr: -------------------------------------------------------------------------------- 1 | class CurrentLogin::Delete < BrowserAction 2 | include Shield::CurrentLogin::Delete 3 | 4 | delete "/login/delete" do 5 | run_operation 6 | end 7 | 8 | def do_run_operation_succeeded(operation, login) 9 | response.headers["X-Current-Login"] = "0" 10 | previous_def 11 | end 12 | 13 | def remote_ip? : Socket::IPAddress? 14 | Socket::IPAddress.new("128.0.0.2", 5000) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_login/destroy.cr: -------------------------------------------------------------------------------- 1 | class CurrentLogin::Destroy < BrowserAction 2 | include Shield::CurrentLogin::Destroy 3 | 4 | delete "/log-out" do 5 | run_operation 6 | end 7 | 8 | def do_run_operation_succeeded(operation, login) 9 | response.headers["X-Current-Login"] = "0" 10 | previous_def 11 | end 12 | 13 | def remote_ip? : Socket::IPAddress? 14 | Socket::IPAddress.new("128.0.0.2", 5000) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_login/new.cr: -------------------------------------------------------------------------------- 1 | class CurrentLogin::New < BrowserAction 2 | include Shield::CurrentLogin::New 3 | 4 | get "/log-in" do 5 | operation = StartCurrentLogin.new(remote_ip: remote_ip?, session: session) 6 | html NewPage, operation: operation 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/bearer_logins/create.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::BearerLogins::Create < BrowserAction 2 | include Shield::CurrentUser::BearerLogins::Create 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | post "/account/bearer-logins" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, bearer_login) 11 | response.headers["X-Bearer-Login-ID"] = bearer_login.id.to_s 12 | response.headers["X-User-ID"] = bearer_login.user_id.to_s 13 | previous_def 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/bearer_logins/delete.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::BearerLogins::Delete < BrowserAction 2 | include Shield::CurrentUser::BearerLogins::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/bearer-logins/delete" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, user) 11 | response.headers["X-User-ID"] = user.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/bearer_logins/destroy.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::BearerLogins::Destroy < BrowserAction 2 | include Shield::CurrentUser::BearerLogins::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/bearer-logins" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, user) 11 | response.headers["X-User-ID"] = user.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/bearer_logins/index.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::BearerLogins::Index < BrowserAction 2 | include Shield::CurrentUser::BearerLogins::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/account/bearer-logins" do 9 | html IndexPage, bearer_logins: bearer_logins, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/bearer_logins/new.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::BearerLogins::New < BrowserAction 2 | include Shield::CurrentUser::BearerLogins::New 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | get "/account/bearer-logins/new" do 7 | operation = CreateBearerLogin.new(user: user) 8 | html NewPage, operation: operation 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/edit.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::Edit < BrowserAction 2 | include Shield::EmailConfirmationCurrentUser::Edit 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | get "/ec/profile/edit" do 7 | operation = UpdateCurrentUser.new( 8 | user, 9 | remote_ip: remote_ip?, 10 | current_login: current_login? 11 | ) 12 | 13 | html EditPage, operation: operation 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/email_confirmations/index.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::EmailConfirmations::Index < BrowserAction 2 | include Shield::CurrentUser::EmailConfirmations::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/account/email-confirmations" do 9 | html IndexPage, email_confirmations: email_confirmations, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/logins/delete.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::Logins::Delete < BrowserAction 2 | include Shield::CurrentUser::Logins::Delete 3 | 4 | delete "/account/logins/delete" do 5 | run_operation 6 | end 7 | 8 | def do_run_operation_succeeded(operation, login) 9 | response.headers["X-Log-Out-Everywhere"] = "true" 10 | previous_def 11 | end 12 | 13 | def remote_ip? : Socket::IPAddress? 14 | Socket::IPAddress.new("128.0.0.2", 5000) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/logins/destroy.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::Logins::Destroy < BrowserAction 2 | include Shield::CurrentUser::Logins::Destroy 3 | 4 | delete "/account/logins" do 5 | run_operation 6 | end 7 | 8 | def do_run_operation_succeeded(operation, login) 9 | response.headers["X-Log-Out-Everywhere"] = "true" 10 | previous_def 11 | end 12 | 13 | def remote_ip? : Socket::IPAddress? 14 | Socket::IPAddress.new("128.0.0.2", 5000) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/logins/index.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::Logins::Index < BrowserAction 2 | include Shield::CurrentUser::Logins::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/account/logins" do 9 | html IndexPage, logins: logins, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/new.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::New < BrowserAction 2 | include Shield::EmailConfirmationCurrentUser::New 3 | 4 | get "/ec/new" do 5 | run_operation 6 | end 7 | 8 | def do_verify_operation_failed(utility) 9 | response.headers["X-Email-Confirmation-Status"] = "failure" 10 | previous_def 11 | end 12 | 13 | def remote_ip? : Socket::IPAddress? 14 | Socket::IPAddress.new("128.0.0.2", 5000) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/oauth_access_tokens/delete.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::OauthAccessTokens::Delete < BrowserAction 2 | include Shield::CurrentUser::OauthAccessTokens::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/oauth/tokens/delete" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, user) 11 | response.headers["X-User-ID"] = user.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/oauth_access_tokens/destroy.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::OauthAccessTokens::Destroy < BrowserAction 2 | include Shield::CurrentUser::OauthAccessTokens::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/oauth/tokens" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, user) 11 | response.headers["X-User-ID"] = user.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/oauth_access_tokens/index.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::OauthAccessTokens::Index < BrowserAction 2 | include Shield::CurrentUser::OauthAccessTokens::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/account/oauth/tokens" do 9 | html BearerLogins::IndexPage, bearer_logins: bearer_logins, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/oauth_clients/create.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::OauthClients::Create < BrowserAction 2 | include Shield::CurrentUser::OauthClients::Create 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | post "/account/oauth/clients" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, oauth_client) 11 | response.headers["X-OAuth-Client-ID"] = oauth_client.id.to_s 12 | response.headers["X-User-ID"] = oauth_client.user_id.to_s 13 | previous_def 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/oauth_clients/delete.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::OauthClients::Delete < BrowserAction 2 | include Shield::CurrentUser::OauthClients::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/oauth/clients/delete" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, user) 11 | response.headers["X-User-ID"] = user.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/oauth_clients/destroy.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::OauthClients::Destroy < BrowserAction 2 | include Shield::CurrentUser::OauthClients::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/oauth/clients" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, user) 11 | response.headers["X-User-ID"] = user.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/oauth_clients/index.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::OauthClients::Index < BrowserAction 2 | include Shield::CurrentUser::OauthClients::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/account/oauth/clients" do 9 | html IndexPage, oauth_clients: oauth_clients, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/oauth_clients/new.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::OauthClients::New < BrowserAction 2 | include Shield::CurrentUser::OauthClients::New 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | get "/account/oauth/clients/new" do 7 | operation = RegisterOauthClient.new(user: user) 8 | html NewPage, operation: operation 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/oauth_grants/delete.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::OauthGrants::Delete < BrowserAction 2 | include Shield::CurrentUser::OauthGrants::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/oauth/grants/delete" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, user) 11 | response.headers["X-User-ID"] = user.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/oauth_grants/destroy.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::OauthGrants::Destroy < BrowserAction 2 | include Shield::CurrentUser::OauthGrants::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/oauth/grants" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, user) 11 | response.headers["X-User-ID"] = user.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/oauth_grants/index.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::OauthGrants::Index < BrowserAction 2 | include Shield::CurrentUser::OauthGrants::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/account/oauth/grants" do 9 | html IndexPage, oauth_grants: oauth_grants, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/oauth_permissions/delete.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::OauthPermissions::Delete < BrowserAction 2 | include Shield::CurrentUser::OauthPermissions::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/oauth/permissions/:oauth_client_id/delete" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, oauth_client) 11 | response.headers["X-OAuth-Client-ID"] = oauth_client.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/oauth_permissions/destroy.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::OauthPermissions::Destroy < BrowserAction 2 | include Shield::CurrentUser::OauthPermissions::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/account/oauth/permissions/:oauth_client_id" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, oauth_client) 11 | response.headers["X-OAuth-Client-ID"] = oauth_client.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/oauth_permissions/index.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::OauthPermissions::Index < BrowserAction 2 | include Shield::CurrentUser::OauthPermissions::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/account/oauth/permissions" do 9 | html IndexPage, oauth_clients: oauth_clients, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/password_resets/index.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::PasswordResets::Index < BrowserAction 2 | include Shield::CurrentUser::PasswordResets::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/account/password-resets" do 9 | html IndexPage, password_resets: password_resets, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/show.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::Show < BrowserAction 2 | include Shield::EmailConfirmationCurrentUser::Show 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | get "/ec/profile" do 7 | html ShowPage, user: user 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/current_user/update.cr: -------------------------------------------------------------------------------- 1 | class CurrentUser::Update < BrowserAction 2 | include Shield::EmailConfirmationCurrentUser::Update 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | patch "/ec/profile" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/email_confirmations/delete.cr: -------------------------------------------------------------------------------- 1 | class EmailConfirmations::Delete < BrowserAction 2 | include Shield::EmailConfirmations::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/email-confirmations/:email_confirmation_id/delete" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, email_confirmation) 11 | response.headers["X-Email-Confirmation-ID"] = email_confirmation.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/email_confirmations/destroy.cr: -------------------------------------------------------------------------------- 1 | class EmailConfirmations::Destroy < BrowserAction 2 | include Shield::EmailConfirmations::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/email-confirmations/:email_confirmation_id" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, email_confirmation) 11 | response.headers["X-Email-Confirmation-ID"] = email_confirmation.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/email_confirmations/index.cr: -------------------------------------------------------------------------------- 1 | class EmailConfirmations::Index < BrowserAction 2 | include Shield::EmailConfirmations::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/email-confirmations" do 9 | html IndexPage, email_confirmations: email_confirmations, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/email_confirmations/new.cr: -------------------------------------------------------------------------------- 1 | class EmailConfirmations::New < BrowserAction 2 | include Shield::EmailConfirmations::New 3 | 4 | get "/email-confirmations/new" do 5 | operation = StartEmailConfirmation.new(remote_ip: remote_ip?) 6 | html NewPage, operation: operation 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/email_confirmations/show.cr: -------------------------------------------------------------------------------- 1 | class EmailConfirmations::Show < BrowserAction 2 | include Shield::EmailConfirmations::Show 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | get "/email-confirmations/:email_confirmation_id" do 7 | html ShowPage, email_confirmation: email_confirmation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/email_confirmations/token/show.cr: -------------------------------------------------------------------------------- 1 | class EmailConfirmations::Token::Show < BrowserAction 2 | include Shield::EmailConfirmations::Token::Show 3 | 4 | get "/email-confirmations/token/:token" do 5 | run_operation 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/email_confirmations/update.cr: -------------------------------------------------------------------------------- 1 | class EmailConfirmations::Update < BrowserAction 2 | include Shield::EmailConfirmations::Update 3 | 4 | skip :pin_email_confirmation_to_ip_address 5 | skip :pin_login_to_ip_address 6 | 7 | get "/email-confirmations/update" do 8 | run_operation 9 | end 10 | 11 | def do_verify_operation_failed(utility) 12 | response.headers["X-Email-Confirmation-Status"] = "failure" 13 | previous_def 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/home/create.cr: -------------------------------------------------------------------------------- 1 | class Home::Create < BrowserAction 2 | skip :require_logged_in 3 | skip :require_logged_out 4 | 5 | post "/" do 6 | json({page: "Home::Create", previous_page: previous_page_url?}) 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/home/edit.cr: -------------------------------------------------------------------------------- 1 | class Home::Edit < BrowserAction 2 | skip :require_logged_in 3 | skip :require_logged_out 4 | 5 | get "/edit" do 6 | redirect_back fallback: Home::Index, allow_external: true 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/home/index.cr: -------------------------------------------------------------------------------- 1 | class Home::Index < BrowserAction 2 | skip :require_logged_in 3 | skip :require_logged_out 4 | 5 | get "/" do 6 | json({page: "Home::Index", previous_page: previous_page_url?}) 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/home/show.cr: -------------------------------------------------------------------------------- 1 | class Home::Show < BrowserAction 2 | skip :require_logged_in 3 | skip :require_logged_out 4 | 5 | get "/show" do 6 | redirect_back fallback: Home::Index 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/home/update.cr: -------------------------------------------------------------------------------- 1 | class Home::Update < BrowserAction 2 | skip :require_logged_in 3 | skip :require_logged_out 4 | 5 | patch "/" do 6 | redirect_back fallback: Home::Show 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/logins/delete.cr: -------------------------------------------------------------------------------- 1 | class Logins::Delete < BrowserAction 2 | include Shield::Logins::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/logins/delete/:login_id" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, login) 11 | response.headers["X-Login-ID"] = login.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/logins/destroy.cr: -------------------------------------------------------------------------------- 1 | class Logins::Destroy < BrowserAction 2 | include Shield::Logins::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/logins/:login_id" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, login) 11 | response.headers["X-Login-ID"] = login.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/logins/index.cr: -------------------------------------------------------------------------------- 1 | class Logins::Index < BrowserAction 2 | include Shield::Logins::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/logins" do 9 | html IndexPage, logins: logins, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/logins/show.cr: -------------------------------------------------------------------------------- 1 | class Logins::Show < BrowserAction 2 | include Shield::Logins::Show 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | get "/logins/:login_id" do 8 | html ShowPage, login: login 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/oauth/authorize.cr: -------------------------------------------------------------------------------- 1 | class Oauth::Authorize < BrowserAction 2 | include Shield::Oauth::Authorize 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | get "/oauth/authorize" do 7 | run_operation 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/oauth_access_tokens/index.cr: -------------------------------------------------------------------------------- 1 | class OauthAccessTokens::Index < BrowserAction 2 | include Shield::OauthAccessTokens::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/oauth/tokens" do 9 | html BearerLogins::IndexPage, bearer_logins: bearer_logins, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/oauth_clients/delete.cr: -------------------------------------------------------------------------------- 1 | class OauthClients::Delete < BrowserAction 2 | include Shield::OauthClients::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/oauth/clients/delete/:oauth_client_id" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, oauth_client) 11 | response.headers["X-OAuth-Client-ID"] = oauth_client.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/oauth_clients/destroy.cr: -------------------------------------------------------------------------------- 1 | class OauthClients::Destroy < BrowserAction 2 | include Shield::OauthClients::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/oauth/clients/:oauth_client_id" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, oauth_client) 11 | response.headers["X-OAuth-Client-ID"] = oauth_client.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/oauth_clients/edit.cr: -------------------------------------------------------------------------------- 1 | class OauthClients::Edit < BrowserAction 2 | include Shield::OauthClients::Edit 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | get "/oauth/clients/:oauth_client_id/edit" do 8 | operation = UpdateOauthClient.new(oauth_client) 9 | html EditPage, operation: operation 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/oauth_clients/index.cr: -------------------------------------------------------------------------------- 1 | class OauthClients::Index < BrowserAction 2 | include Shield::OauthClients::Index 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | param page : Int32 = 1 8 | 9 | get "/oauth/clients" do 10 | html IndexPage, oauth_clients: oauth_clients, pages: pages 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/oauth_clients/secret/show.cr: -------------------------------------------------------------------------------- 1 | class OauthClients::Secret::Show < BrowserAction 2 | include Shield::OauthClients::Secret::Show 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | get "/oauth/clients/secret" do 8 | html ShowPage, oauth_client: oauth_client?, secret: secret? 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/oauth_clients/secret/update.cr: -------------------------------------------------------------------------------- 1 | class OauthClients::Secret::Update < BrowserAction 2 | include Shield::OauthClients::Secret::Update 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | patch "/oauth/clients/:oauth_client_id/secret" do 8 | run_operation 9 | end 10 | 11 | def do_run_operation_succeeded(operation, oauth_client) 12 | response.headers["X-OAuth-Client-ID"] = oauth_client.id.to_s 13 | previous_def 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/oauth_clients/show.cr: -------------------------------------------------------------------------------- 1 | class OauthClients::Show < BrowserAction 2 | include Shield::OauthClients::Show 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | get "/oauth/clients/:oauth_client_id" do 8 | html ShowPage, oauth_client: oauth_client 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/oauth_clients/update.cr: -------------------------------------------------------------------------------- 1 | class OauthClients::Update < BrowserAction 2 | include Shield::OauthClients::Update 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | patch "/oauth/clients/:oauth_client_id" do 8 | run_operation 9 | end 10 | 11 | def do_run_operation_succeeded(operation, oauth_client) 12 | response.headers["X-OAuth-Client-ID"] = oauth_client.id.to_s 13 | previous_def 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/oauth_clients/users/index.cr: -------------------------------------------------------------------------------- 1 | class OauthClients::Users::Index < BrowserAction 2 | include Shield::OauthClients::Users::Index 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | param page : Int32 = 1 8 | 9 | get "/oauth/clients/:oauth_client_id/users" do 10 | html IndexPage, users: users, oauth_client: oauth_client, pages: pages 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/oauth_grants/delete.cr: -------------------------------------------------------------------------------- 1 | class OauthGrants::Delete < BrowserAction 2 | include Shield::OauthGrants::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/oauth/grants/:oauth_grant_id/delete" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, oauth_grant) 11 | response.headers["X-OAuth-Grant-ID"] = oauth_grant.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/oauth_grants/destroy.cr: -------------------------------------------------------------------------------- 1 | class OauthGrants::Destroy < BrowserAction 2 | include Shield::OauthGrants::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/oauth/grants/:oauth_grant_id" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, oauth_grant) 11 | response.headers["X-OAuth-Grant-ID"] = oauth_grant.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/oauth_grants/index.cr: -------------------------------------------------------------------------------- 1 | class OauthGrants::Index < BrowserAction 2 | include Shield::OauthGrants::Index 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | param page : Int32 = 1 8 | 9 | get "/oauth/grants" do 10 | html IndexPage, oauth_grants: oauth_grants, pages: pages 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/oauth_grants/show.cr: -------------------------------------------------------------------------------- 1 | class OauthGrants::Show < BrowserAction 2 | include Shield::OauthGrants::Show 3 | 4 | skip :check_authorization 5 | skip :pin_login_to_ip_address 6 | 7 | get "/oauth/grants/:oauth_grant_id" do 8 | html ShowPage, oauth_grant: oauth_grant 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/password_resets/create.cr: -------------------------------------------------------------------------------- 1 | class PasswordResets::Create < BrowserAction 2 | include Shield::PasswordResets::Create 3 | 4 | post "/password-resets" do 5 | run_operation 6 | end 7 | 8 | def do_run_operation_succeeded(operation, password_reset) 9 | response.headers["X-Password-Reset-ID"] = "pr_id" 10 | previous_def 11 | end 12 | 13 | private def success_action(operation) 14 | response.headers["X-Password-Reset-Status"] = "success" 15 | previous_def 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/password_resets/delete.cr: -------------------------------------------------------------------------------- 1 | class PasswordResets::Delete < BrowserAction 2 | include Shield::PasswordResets::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/password-resets/:password_reset_id/delete" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, password_reset) 11 | response.headers["X-Password-Reset-ID"] = password_reset.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/password_resets/destroy.cr: -------------------------------------------------------------------------------- 1 | class PasswordResets::Destroy < BrowserAction 2 | include Shield::PasswordResets::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/password-resets/:password_reset_id" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, password_reset) 11 | response.headers["X-Password-Reset-ID"] = password_reset.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/password_resets/edit.cr: -------------------------------------------------------------------------------- 1 | class PasswordResets::Edit < BrowserAction 2 | include Shield::PasswordResets::Edit 3 | 4 | get "/password-resets/edit" do 5 | run_operation 6 | end 7 | 8 | def remote_ip? : Socket::IPAddress? 9 | Socket::IPAddress.new("128.0.0.2", 5000) 10 | end 11 | 12 | def do_verify_operation_failed(utility) 13 | response.headers["X-Password-Reset-Status"] = "failure" 14 | previous_def 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/password_resets/index.cr: -------------------------------------------------------------------------------- 1 | class PasswordResets::Index < BrowserAction 2 | include Shield::PasswordResets::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/password-resets" do 9 | html IndexPage, password_resets: password_resets, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/password_resets/new.cr: -------------------------------------------------------------------------------- 1 | class PasswordResets::New < BrowserAction 2 | include Shield::PasswordResets::New 3 | 4 | get "/password-resets/new" do 5 | operation = StartPasswordReset.new(remote_ip: remote_ip?) 6 | html NewPage, operation: operation 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/password_resets/show.cr: -------------------------------------------------------------------------------- 1 | class PasswordResets::Show < BrowserAction 2 | include Shield::PasswordResets::Show 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | get "/password-resets/:password_reset_id" do 7 | html ShowPage, password_reset: password_reset 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/password_resets/token/show.cr: -------------------------------------------------------------------------------- 1 | class PasswordResets::Token::Show < BrowserAction 2 | include Shield::PasswordResets::Token::Show 3 | 4 | get "/password-resets/token/:token" do 5 | run_operation 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/password_resets/update.cr: -------------------------------------------------------------------------------- 1 | class PasswordResets::Update < BrowserAction 2 | include Shield::PasswordResets::Update 3 | 4 | patch "/password-resets" do 5 | run_operation 6 | end 7 | 8 | def do_verify_operation_failed(utility) 9 | response.headers["X-Password-Reset-Status"] = "failure" 10 | previous_def 11 | end 12 | 13 | def remote_ip? : Socket::IPAddress? 14 | Socket::IPAddress.new("129.0.0.5", 6000) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/posts/new.cr: -------------------------------------------------------------------------------- 1 | class Posts::New < BrowserAction 2 | skip :require_logged_out 3 | skip :pin_login_to_ip_address 4 | 5 | get "/posts/new" do 6 | json({action: "Posts::New"}) 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/regular_current_user/edit.cr: -------------------------------------------------------------------------------- 1 | class RegularCurrentUser::Edit < BrowserAction 2 | include Shield::CurrentUser::Edit 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | get "/profile/edit" do 7 | operation = UpdateRegularCurrentUser.new( 8 | user, 9 | current_login: current_login? 10 | ) 11 | 12 | html EditPage, operation: operation 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/regular_current_user/new.cr: -------------------------------------------------------------------------------- 1 | class RegularCurrentUser::New < BrowserAction 2 | include Shield::CurrentUser::New 3 | 4 | get "/register" do 5 | operation = RegisterRegularCurrentUser.new 6 | html NewPage, operation: operation 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/regular_current_user/show.cr: -------------------------------------------------------------------------------- 1 | class RegularCurrentUser::Show < BrowserAction 2 | include Shield::CurrentUser::Show 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | get "/profile" do 7 | html ShowPage, user: user 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/bearer_logins/delete.cr: -------------------------------------------------------------------------------- 1 | class Users::BearerLogins::Delete < BrowserAction 2 | include Shield::Users::BearerLogins::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/bearer-logins/delete" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, user) 11 | response.headers["X-User-ID"] = user.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/bearer_logins/destroy.cr: -------------------------------------------------------------------------------- 1 | class Users::BearerLogins::Destroy < BrowserAction 2 | include Shield::Users::BearerLogins::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/bearer-logins" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, user) 11 | response.headers["X-User-ID"] = user.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/bearer_logins/index.cr: -------------------------------------------------------------------------------- 1 | class Users::BearerLogins::Index < BrowserAction 2 | include Shield::Users::BearerLogins::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/users/:user_id/bearer-logins" do 9 | html IndexPage, bearer_logins: bearer_logins, user: user, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/create.cr: -------------------------------------------------------------------------------- 1 | class Users::Create < BrowserAction 2 | include Shield::Users::Create 3 | 4 | skip :pin_login_to_ip_address 5 | skip :check_authorization 6 | 7 | post "/users" do 8 | run_operation 9 | end 10 | 11 | def do_run_operation_succeeded(operation, user) 12 | response.headers["X-User-ID"] = "user_id" 13 | previous_def 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/delete.cr: -------------------------------------------------------------------------------- 1 | class Users::Delete < BrowserAction 2 | include Shield::Users::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | skip :check_authorization 6 | 7 | delete "/users/:user_id" do 8 | run_operation 9 | end 10 | 11 | def do_run_operation_succeeded(operation, user) 12 | response.headers["X-User-ID"] = "user_id" 13 | previous_def 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/edit.cr: -------------------------------------------------------------------------------- 1 | class Users::Edit < BrowserAction 2 | include Shield::Users::Edit 3 | 4 | skip :check_authorization 5 | 6 | get "/users/:user_id/edit" do 7 | operation = UpdateUser.new(user, current_login: current_login?) 8 | html EditPage, operation: operation 9 | end 10 | 11 | def remote_ip? : Socket::IPAddress? 12 | Socket::IPAddress.new("129.0.0.5", 6000) 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/email_confirmations/delete.cr: -------------------------------------------------------------------------------- 1 | class Users::EmailConfirmations::Delete < BrowserAction 2 | include Shield::Users::EmailConfirmations::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/email-confirmations/delete" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, email_confirmation) 11 | response.headers["X-End-Email-Confirmations"] = "true" 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/email_confirmations/destroy.cr: -------------------------------------------------------------------------------- 1 | class Users::EmailConfirmations::Destroy < BrowserAction 2 | include Shield::Users::EmailConfirmations::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/email-confirmations" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, email_confirmation) 11 | response.headers["X-End-Email-Confirmations"] = "true" 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/email_confirmations/index.cr: -------------------------------------------------------------------------------- 1 | class Users::EmailConfirmations::Index < BrowserAction 2 | include Shield::Users::EmailConfirmations::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/users/:user_id/email-confirmations" do 9 | html IndexPage, 10 | email_confirmations: email_confirmations, 11 | user: user, 12 | pages: pages 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/index.cr: -------------------------------------------------------------------------------- 1 | class Users::Index < BrowserAction 2 | include Shield::Users::Index 3 | 4 | skip :pin_login_to_ip_address 5 | skip :check_authorization 6 | 7 | param page : Int32 = 1 8 | 9 | get "/users" do 10 | html IndexPage, users: users, pages: pages 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/logins/delete.cr: -------------------------------------------------------------------------------- 1 | class Users::Logins::Delete < BrowserAction 2 | include Shield::Users::Logins::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/logins/delete" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, login) 11 | response.headers["X-Log-Out-Everywhere"] = "true" 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/logins/destroy.cr: -------------------------------------------------------------------------------- 1 | class Users::Logins::Destroy < BrowserAction 2 | include Shield::Users::Logins::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/logins" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, login) 11 | response.headers["X-Log-Out-Everywhere"] = "true" 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/logins/index.cr: -------------------------------------------------------------------------------- 1 | class Users::Logins::Index < BrowserAction 2 | include Shield::Users::Logins::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/users/:user_id/logins" do 9 | html IndexPage, logins: logins, user: user, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/new.cr: -------------------------------------------------------------------------------- 1 | class Users::New < BrowserAction 2 | include Shield::Users::New 3 | 4 | skip :pin_login_to_ip_address 5 | skip :check_authorization 6 | 7 | get "/users/new" do 8 | operation = RegisterUser.new 9 | html NewPage, operation: operation 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/oauth_access_tokens/delete.cr: -------------------------------------------------------------------------------- 1 | class Users::OauthAccessTokens::Delete < BrowserAction 2 | include Shield::Users::OauthAccessTokens::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/oauth/tokens/delete" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, user) 11 | response.headers["X-User-ID"] = user.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/oauth_access_tokens/destroy.cr: -------------------------------------------------------------------------------- 1 | class Users::OauthAccessTokens::Destroy < BrowserAction 2 | include Shield::Users::OauthAccessTokens::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/oauth/tokens" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, user) 11 | response.headers["X-User-ID"] = user.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/oauth_access_tokens/index.cr: -------------------------------------------------------------------------------- 1 | class Users::OauthAccessTokens::Index < BrowserAction 2 | include Shield::Users::OauthAccessTokens::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/users/:user_id/oauth/tokens" do 9 | html BearerLogins::IndexPage, 10 | bearer_logins: bearer_logins, 11 | user: user, 12 | pages: pages 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/oauth_clients/delete.cr: -------------------------------------------------------------------------------- 1 | class Users::OauthClients::Delete < BrowserAction 2 | include Shield::Users::OauthClients::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/oauth/clients/delete" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, user) 11 | response.headers["X-User-ID"] = user.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/oauth_clients/destroy.cr: -------------------------------------------------------------------------------- 1 | class Users::OauthClients::Destroy < BrowserAction 2 | include Shield::Users::OauthClients::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/oauth/clients" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, user) 11 | response.headers["X-User-ID"] = user.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/oauth_clients/index.cr: -------------------------------------------------------------------------------- 1 | class Users::OauthClients::Index < BrowserAction 2 | include Shield::Users::OauthClients::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/users/:user_id/oauth/clients" do 9 | html IndexPage, oauth_clients: oauth_clients, user: user, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/oauth_grants/delete.cr: -------------------------------------------------------------------------------- 1 | class Users::OauthGrants::Delete < BrowserAction 2 | include Shield::Users::OauthGrants::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/oauth/grants/delete" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, user) 11 | response.headers["X-User-ID"] = user.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/oauth_grants/destroy.cr: -------------------------------------------------------------------------------- 1 | class Users::OauthGrants::Destroy < BrowserAction 2 | include Shield::Users::OauthGrants::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/oauth/grants" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, user) 11 | response.headers["X-User-ID"] = user.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/oauth_grants/index.cr: -------------------------------------------------------------------------------- 1 | class Users::OauthGrants::Index < BrowserAction 2 | include Shield::Users::OauthGrants::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/users/:user_id/oauth/grants" do 9 | html IndexPage, oauth_grants: oauth_grants, user: user, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/oauth_permissions/delete.cr: -------------------------------------------------------------------------------- 1 | class Users::OauthPermissions::Delete < BrowserAction 2 | include Shield::Users::OauthPermissions::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/oauth/permissions/:oauth_client_id/delete" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, oauth_client) 11 | response.headers["X-OAuth-Client-ID"] = oauth_client.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/oauth_permissions/destroy.cr: -------------------------------------------------------------------------------- 1 | class Users::OauthPermissions::Destroy < BrowserAction 2 | include Shield::Users::OauthPermissions::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/oauth/permissions/:oauth_client_id" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, oauth_client) 11 | response.headers["X-OAuth-Client-ID"] = oauth_client.id.to_s 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/oauth_permissions/index.cr: -------------------------------------------------------------------------------- 1 | class Users::OauthPermissions::Index < BrowserAction 2 | include Shield::Users::OauthPermissions::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/users/:user_id/oauth/permissions" do 9 | html IndexPage, oauth_clients: oauth_clients, user: user, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/password_resets/delete.cr: -------------------------------------------------------------------------------- 1 | class Users::PasswordResets::Delete < BrowserAction 2 | include Shield::Users::PasswordResets::Delete 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/password-resets/delete" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, password_reset) 11 | response.headers["X-End-Password-Resets"] = "true" 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/password_resets/destroy.cr: -------------------------------------------------------------------------------- 1 | class Users::PasswordResets::Destroy < BrowserAction 2 | include Shield::Users::PasswordResets::Destroy 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | delete "/users/:user_id/password-resets" do 7 | run_operation 8 | end 9 | 10 | def do_run_operation_succeeded(operation, password_reset) 11 | response.headers["X-End-Password-Resets"] = "true" 12 | previous_def 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/password_resets/index.cr: -------------------------------------------------------------------------------- 1 | class Users::PasswordResets::Index < BrowserAction 2 | include Shield::Users::PasswordResets::Index 3 | 4 | skip :pin_login_to_ip_address 5 | 6 | param page : Int32 = 1 7 | 8 | get "/users/:user_id/password-resets" do 9 | html IndexPage, password_resets: password_resets, user: user, pages: pages 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/show.cr: -------------------------------------------------------------------------------- 1 | class Users::Show < BrowserAction 2 | include Shield::Users::Show 3 | 4 | skip :check_authorization 5 | 6 | get "/users/:user_id" do 7 | html ShowPage, user: user 8 | end 9 | 10 | def remote_ip? : Socket::IPAddress? 11 | Socket::IPAddress.new("128.0.0.2", 5000) 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/support/app/src/actions/users/update.cr: -------------------------------------------------------------------------------- 1 | class Users::Update < BrowserAction 2 | include Shield::Users::Update 3 | 4 | skip :pin_login_to_ip_address 5 | skip :check_authorization 6 | 7 | patch "/users/:user_id" do 8 | run_operation 9 | end 10 | 11 | def do_run_operation_succeeded(operation, user) 12 | response.headers["X-User-ID"] = user.id.to_s 13 | previous_def 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/app/src/app_database.cr: -------------------------------------------------------------------------------- 1 | class AppDatabase < Avram::Database 2 | end 3 | -------------------------------------------------------------------------------- /spec/support/app/src/app_server.cr: -------------------------------------------------------------------------------- 1 | class AppServer < Lucky::BaseAppServer 2 | def middleware : Array(HTTP::Handler) 3 | [ 4 | Lucky::HttpMethodOverrideHandler.new, 5 | Lucky::ErrorHandler.new(action: Errors::Show), 6 | Lucky::RouteHandler.new, 7 | Lucky::RouteNotFoundHandler.new, 8 | ] of HTTP::Handler 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/emails/base_email.cr: -------------------------------------------------------------------------------- 1 | abstract class BaseEmail < Carbon::Email 2 | from sender 3 | to receivers 4 | subject heading 5 | 6 | def sender 7 | default_sender 8 | end 9 | 10 | abstract def receivers 11 | 12 | abstract def heading 13 | 14 | def text_body 15 | text_message 16 | end 17 | 18 | private abstract def text_message 19 | 20 | private def default_sender 21 | Carbon::Address.new("Shield", "noreply@example.tld") 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /spec/support/app/src/emails/bearer_login_notification_email.cr: -------------------------------------------------------------------------------- 1 | class BearerLoginNotificationEmail < BaseEmail 2 | def initialize( 3 | @operation : BearerLogin::SaveOperation, 4 | @bearer_login : BearerLogin 5 | ) 6 | end 7 | 8 | private def receivers 9 | @bearer_login.user 10 | end 11 | 12 | private def heading 13 | "New bearer login created" 14 | end 15 | 16 | private def text_message : String 17 | <<-TEXT 18 | New bearer login token created 19 | TEXT 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /spec/support/app/src/emails/guest_password_reset_request_email.cr: -------------------------------------------------------------------------------- 1 | class GuestPasswordResetRequestEmail < BaseEmail 2 | def initialize(@operation : StartPasswordReset) : Nil 3 | end 4 | 5 | private def receivers 6 | Carbon::Address.new(@operation.email.value.to_s) 7 | end 8 | 9 | private def heading 10 | "Password reset attempt failed" 11 | end 12 | 13 | private def text_message : String 14 | <<-TEXT 15 | Password reset attempt failed 16 | TEXT 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/support/app/src/emails/login_notification_email.cr: -------------------------------------------------------------------------------- 1 | class LoginNotificationEmail < BaseEmail 2 | def initialize(@operation : Login::SaveOperation, @login : Login) 3 | end 4 | 5 | private def receivers 6 | @login.user 7 | end 8 | 9 | private def heading 10 | "Someone logged in into your account" 11 | end 12 | 13 | private def text_message : String 14 | <<-TEXT 15 | Someone logged in into your account 16 | TEXT 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/support/app/src/emails/oauth_access_token_notification_email.cr: -------------------------------------------------------------------------------- 1 | class OauthAccessTokenNotificationEmail < BaseEmail 2 | def initialize( 3 | @operation : BearerLogin::SaveOperation, 4 | @bearer_login : BearerLogin 5 | ) 6 | end 7 | 8 | private def receivers 9 | @bearer_login.user 10 | end 11 | 12 | private def heading 13 | "New OAuth access token created" 14 | end 15 | 16 | private def text_message 17 | <<-TEXT 18 | New OAuth access token created 19 | TEXT 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /spec/support/app/src/emails/password_change_notification_email.cr: -------------------------------------------------------------------------------- 1 | class PasswordChangeNotificationEmail < BaseEmail 2 | def initialize(@operation : User::SaveOperation, @user : User) : Nil 3 | end 4 | 5 | private def receivers 6 | @user 7 | end 8 | 9 | private def heading 10 | "Your password was recently changed" 11 | end 12 | 13 | private def text_message : String 14 | <<-TEXT 15 | Your password was recently changed 16 | TEXT 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/support/app/src/emails/user_email_confirmation_request_email.cr: -------------------------------------------------------------------------------- 1 | class UserEmailConfirmationRequestEmail < BaseEmail 2 | def initialize(@operation : StartEmailConfirmation) : Nil 3 | end 4 | 5 | private def receivers 6 | Carbon::Address.new(@operation.email.value.to_s) 7 | end 8 | 9 | private def heading 10 | "Email change attempt failed" 11 | end 12 | 13 | private def text_message : String 14 | <<-TEXT 15 | Email change attempt failed 16 | TEXT 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/support/app/src/emails/user_welcome_email.cr: -------------------------------------------------------------------------------- 1 | class UserWelcomeEmail < BaseEmail 2 | def initialize(@operation : User::SaveOperation) : Nil 3 | end 4 | 5 | private def receivers 6 | Carbon::Address.new(@operation.email.value.to_s) 7 | end 8 | 9 | private def heading 10 | "Registration failed" 11 | end 12 | 13 | private def text_message : String 14 | <<-TEXT 15 | Registration failed 16 | TEXT 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/support/app/src/emails/welcome_email.cr: -------------------------------------------------------------------------------- 1 | class WelcomeEmail < BaseEmail 2 | def initialize(@operation : User::SaveOperation, @user : User) : Nil 3 | end 4 | 5 | private def receivers 6 | @user 7 | end 8 | 9 | private def heading 10 | "Welcome" 11 | end 12 | 13 | private def text_message : String 14 | <<-TEXT 15 | Welcome 16 | TEXT 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/support/app/src/models/base_model.cr: -------------------------------------------------------------------------------- 1 | abstract class BaseModel < Avram::Model 2 | def self.database : Avram::Database.class 3 | AppDatabase 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/support/app/src/models/bearer_login.cr: -------------------------------------------------------------------------------- 1 | class BearerLogin < BaseModel 2 | include Shield::BearerLogin 3 | include Shield::OptionalBelongsToOauthClient 4 | 5 | skip_default_columns 6 | primary_key id : Int64 7 | 8 | table :bearer_logins {} 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/models/email_confirmation.cr: -------------------------------------------------------------------------------- 1 | class EmailConfirmation < BaseModel 2 | include Shield::EmailConfirmation 3 | 4 | skip_default_columns 5 | primary_key id : Int64 6 | 7 | table :email_confirmations {} 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/models/login.cr: -------------------------------------------------------------------------------- 1 | class Login < BaseModel 2 | include Shield::Login 3 | 4 | skip_default_columns 5 | primary_key id : Int64 6 | 7 | table :logins {} 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/models/oauth_client.cr: -------------------------------------------------------------------------------- 1 | class OauthClient < BaseModel 2 | include Shield::OauthClient 3 | include Shield::HasManyOauthGrants 4 | 5 | skip_default_columns 6 | primary_key id : UUID 7 | 8 | table :oauth_clients {} 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/models/oauth_grant.cr: -------------------------------------------------------------------------------- 1 | class OauthGrant < BaseModel 2 | include Shield::OauthGrant 3 | 4 | skip_default_columns 5 | primary_key id : Int64 6 | 7 | table :oauth_grants {} 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/models/password_reset.cr: -------------------------------------------------------------------------------- 1 | class PasswordReset < BaseModel 2 | include Shield::PasswordReset 3 | 4 | skip_default_columns 5 | primary_key id : Int64 6 | 7 | table :password_resets {} 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/models/user_options.cr: -------------------------------------------------------------------------------- 1 | class UserOptions < BaseModel 2 | include Shield::UserOptions 3 | include Shield::LoginUserOptionsColumns 4 | include Shield::BearerLoginUserOptionsColumns 5 | include Shield::OauthClientUserOptionsColumns 6 | 7 | table :user_options {} 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/models/user_settings.cr: -------------------------------------------------------------------------------- 1 | struct UserSettings 2 | include Shield::UserSettings 3 | include Shield::BearerLoginUserSettings 4 | include Shield::LoginUserSettings 5 | include Shield::OauthClientUserSettings 6 | end 7 | -------------------------------------------------------------------------------- /spec/support/app/src/operations/register_current_user.cr: -------------------------------------------------------------------------------- 1 | class RegisterCurrentUser < User::SaveOperation 2 | include Shield::SendWelcomeEmail 3 | 4 | before_save set_level 5 | 6 | private def set_level 7 | level.value = User::Level.new(:author) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/operations/register_current_user_2.cr: -------------------------------------------------------------------------------- 1 | require "./save_user_options_2" 2 | 3 | class RegisterCurrentUser2 < User::SaveOperation 4 | include Shield::RegisterEmailConfirmationUser 5 | 6 | has_one save_user_options : SaveUserOptions2 7 | 8 | before_save set_level 9 | 10 | private def set_level 11 | level.value = User::Level.new(:author) 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/support/app/src/operations/register_regular_current_user.cr: -------------------------------------------------------------------------------- 1 | class RegisterRegularCurrentUser < User::SaveOperation 2 | include Shield::RegisterUser 3 | include Shield::HasOneSaveUserOptions 4 | 5 | before_save set_level 6 | 7 | private def set_level 8 | level.value = User::Level.new(:author) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/operations/register_regular_current_user_2.cr: -------------------------------------------------------------------------------- 1 | require "./save_user_options_2" 2 | 3 | class RegisterRegularCurrentUser2 < User::SaveOperation 4 | include Shield::RegisterUser 5 | 6 | has_one save_user_options : SaveUserOptions2 7 | 8 | before_save set_level 9 | 10 | private def set_level 11 | level.value = User::Level.new(:author) 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /spec/support/app/src/operations/register_user.cr: -------------------------------------------------------------------------------- 1 | class RegisterUser < User::SaveOperation 2 | permit_columns :level 3 | 4 | before_save do 5 | validate_required level 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/operations/save_user_options_2.cr: -------------------------------------------------------------------------------- 1 | class SaveUserOptions2 < UserOptions::SaveOperation 2 | include Shield::SaveUserOptions 3 | 4 | before_save error_on_purpose 5 | 6 | private def error_on_purpose 7 | login_notify.add_error "has failed on purpose" 8 | password_notify.add_error "has failed on purpose" 9 | bearer_login_notify.add_error "has failed on purpose" 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/operations/update_current_user.cr: -------------------------------------------------------------------------------- 1 | class UpdateCurrentUser < User::SaveOperation 2 | before_save set_level 3 | 4 | private def set_level 5 | level.value = User::Level.new(:author) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/operations/update_current_user_2.cr: -------------------------------------------------------------------------------- 1 | class UpdateCurrentUser2 < User::SaveOperation 2 | include Shield::UpdateEmailConfirmationUser 3 | 4 | has_one save_user_options : SaveUserOptions2 5 | 6 | before_save set_level 7 | 8 | private def set_level 9 | level.value = User::Level.new(:author) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/operations/update_regular_current_user.cr: -------------------------------------------------------------------------------- 1 | class UpdateRegularCurrentUser < User::SaveOperation 2 | include Shield::UpdateUser 3 | include Shield::HasOneSaveUserOptions 4 | include Shield::NotifyPasswordChange 5 | 6 | before_save set_level 7 | 8 | private def set_level 9 | level.value = User::Level.new(:author) 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /spec/support/app/src/operations/update_regular_current_user_2.cr: -------------------------------------------------------------------------------- 1 | require "./save_user_options_2" 2 | 3 | class UpdateRegularCurrentUser2 < User::SaveOperation 4 | include Shield::UpdateUser 5 | # include Shield::NotifyPasswordChange 6 | 7 | has_one save_user_options : SaveUserOptions2 8 | 9 | before_save set_level 10 | 11 | private def set_level 12 | level.value = User::Level.new(:author) 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /spec/support/app/src/operations/update_user.cr: -------------------------------------------------------------------------------- 1 | class UpdateUser < User::SaveOperation 2 | permit_columns :level 3 | 4 | before_save do 5 | validate_required level 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/bearer_logins/edit_page.cr: -------------------------------------------------------------------------------- 1 | struct BearerLogins::EditPage < MainLayout 2 | needs operation : UpdateBearerLogin 3 | 4 | def content 5 | text "BearerLogins::EditPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/bearer_logins/index_page.cr: -------------------------------------------------------------------------------- 1 | struct BearerLogins::IndexPage < MainLayout 2 | needs bearer_logins : Array(BearerLogin) 3 | needs pages : Lucky::Paginator 4 | 5 | def content 6 | text "BearerLogins::IndexPage" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/bearer_logins/show_page.cr: -------------------------------------------------------------------------------- 1 | struct BearerLogins::ShowPage < MainLayout 2 | needs bearer_login : BearerLogin 3 | 4 | def content 5 | text "BearerLogins::ShowPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/bearer_logins/token/show_page.cr: -------------------------------------------------------------------------------- 1 | struct BearerLogins::Token::ShowPage < MainLayout 2 | needs bearer_login : BearerLogin? 3 | needs token : String? 4 | 5 | def content 6 | text "BearerLogins::Token::ShowPage:#{token}" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/current_login/new_page.cr: -------------------------------------------------------------------------------- 1 | struct CurrentLogin::NewPage < MainLayout 2 | needs operation : StartCurrentLogin 3 | 4 | def content 5 | text "CurrentLogin::NewPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/current_user/bearer_logins/index_page.cr: -------------------------------------------------------------------------------- 1 | struct CurrentUser::BearerLogins::IndexPage < MainLayout 2 | needs bearer_logins : Array(BearerLogin) 3 | needs pages : Lucky::Paginator 4 | 5 | def content 6 | text "CurrentUser::BearerLogins::IndexPage" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/current_user/bearer_logins/new_page.cr: -------------------------------------------------------------------------------- 1 | struct CurrentUser::BearerLogins::NewPage < MainLayout 2 | needs operation : CreateBearerLogin 3 | 4 | def content 5 | text "CurrentUser::BearerLogins::NewPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/current_user/edit_page.cr: -------------------------------------------------------------------------------- 1 | struct CurrentUser::EditPage < MainLayout 2 | needs operation : UpdateCurrentUser 3 | 4 | def content 5 | text "CurrentUser::EditPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/current_user/email_confirmations/index_page.cr: -------------------------------------------------------------------------------- 1 | struct CurrentUser::EmailConfirmations::IndexPage < MainLayout 2 | needs email_confirmations : Array(EmailConfirmation) 3 | needs pages : Lucky::Paginator 4 | 5 | def content 6 | text "CurrentUser::EmailConfirmations::IndexPage" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/current_user/logins/index_page.cr: -------------------------------------------------------------------------------- 1 | struct CurrentUser::Logins::IndexPage < MainLayout 2 | needs logins : Array(Login) 3 | needs pages : Lucky::Paginator 4 | 5 | def content 6 | text "CurrentUser::Logins::IndexPage" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/current_user/new_page.cr: -------------------------------------------------------------------------------- 1 | struct CurrentUser::NewPage < MainLayout 2 | needs operation : RegisterCurrentUser 3 | 4 | def content 5 | text "CurrentUser::NewPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/current_user/oauth_clients/index_page.cr: -------------------------------------------------------------------------------- 1 | struct CurrentUser::OauthClients::IndexPage < MainLayout 2 | needs oauth_clients : Array(OauthClient) 3 | needs pages : Lucky::Paginator 4 | 5 | def content 6 | text "CurrentUser::OauthClients::IndexPage" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/current_user/oauth_clients/new_page.cr: -------------------------------------------------------------------------------- 1 | struct CurrentUser::OauthClients::NewPage < MainLayout 2 | needs operation : RegisterOauthClient 3 | 4 | def content 5 | text "CurrentUser::OauthClients::NewPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/current_user/oauth_grants/index_page.cr: -------------------------------------------------------------------------------- 1 | struct CurrentUser::OauthGrants::IndexPage < MainLayout 2 | needs oauth_grants : Array(OauthGrant) 3 | needs pages : Lucky::Paginator 4 | 5 | def content 6 | text "CurrentUser::OauthGrants::IndexPage" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/current_user/oauth_permissions/index_page.cr: -------------------------------------------------------------------------------- 1 | struct CurrentUser::OauthPermissions::IndexPage < MainLayout 2 | needs oauth_clients : Array(OauthClient) 3 | needs pages : Lucky::Paginator 4 | 5 | def content 6 | text "CurrentUser::OauthPermissions::IndexPage" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/current_user/password_resets/index_page.cr: -------------------------------------------------------------------------------- 1 | struct CurrentUser::PasswordResets::IndexPage < MainLayout 2 | needs password_resets : Array(PasswordReset) 3 | needs pages : Lucky::Paginator 4 | 5 | def content 6 | text "CurrentUser::PasswordResets::IndexPage" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/current_user/show_page.cr: -------------------------------------------------------------------------------- 1 | struct CurrentUser::ShowPage < MainLayout 2 | needs user : User 3 | 4 | def content 5 | text "CurrentUser::ShowPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/email_confirmations/index_page.cr: -------------------------------------------------------------------------------- 1 | struct EmailConfirmations::IndexPage < MainLayout 2 | needs email_confirmations : Array(EmailConfirmation) 3 | needs pages : Lucky::Paginator 4 | 5 | def content 6 | text "EmailConfirmations::IndexPage" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/email_confirmations/new_page.cr: -------------------------------------------------------------------------------- 1 | struct EmailConfirmations::NewPage < MainLayout 2 | needs operation : StartEmailConfirmation 3 | 4 | def content 5 | text "EmailConfirmations::NewPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/email_confirmations/show_page.cr: -------------------------------------------------------------------------------- 1 | struct EmailConfirmations::ShowPage < MainLayout 2 | needs email_confirmation : EmailConfirmation 3 | 4 | def content 5 | text "EmailConfirmations::ShowPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/logins/index_page.cr: -------------------------------------------------------------------------------- 1 | struct Logins::IndexPage < MainLayout 2 | needs logins : Array(Login) 3 | needs pages : Lucky::Paginator 4 | 5 | def content 6 | text "Logins::IndexPage" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/logins/show_page.cr: -------------------------------------------------------------------------------- 1 | struct Logins::ShowPage < MainLayout 2 | needs login : Login 3 | 4 | def content 5 | text "Logins::ShowPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/main_layout.cr: -------------------------------------------------------------------------------- 1 | abstract struct MainLayout 2 | include Lucky::HTMLPage 3 | 4 | def render 5 | current_user? # Just to be sure it compiles 6 | content 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/oauth/authorization/new_page.cr: -------------------------------------------------------------------------------- 1 | struct Oauth::Authorization::NewPage < MainLayout 2 | needs operation : StartOauthGrant 3 | 4 | def content 5 | text "Oauth::Authorization::NewPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/oauth_clients/edit_page.cr: -------------------------------------------------------------------------------- 1 | struct OauthClients::EditPage < MainLayout 2 | needs operation : UpdateOauthClient 3 | 4 | def content 5 | text "OauthClients::EditPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/oauth_clients/index_page.cr: -------------------------------------------------------------------------------- 1 | struct OauthClients::IndexPage < MainLayout 2 | needs oauth_clients : Array(OauthClient) 3 | needs pages : Lucky::Paginator 4 | 5 | def content 6 | text "OauthClients::IndexPage" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/oauth_clients/secret/show_page.cr: -------------------------------------------------------------------------------- 1 | struct OauthClients::Secret::ShowPage < MainLayout 2 | needs oauth_client : OauthClient? 3 | needs secret : String? 4 | 5 | def content 6 | text secret.to_s if secret 7 | text ":" if secret && oauth_client 8 | text oauth_client.try(&.id).to_s if oauth_client 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/oauth_clients/show_page.cr: -------------------------------------------------------------------------------- 1 | struct OauthClients::ShowPage < MainLayout 2 | needs oauth_client : OauthClient 3 | 4 | def content 5 | text "OauthClients::ShowPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/oauth_clients/users/index_page.cr: -------------------------------------------------------------------------------- 1 | struct OauthClients::Users::IndexPage < MainLayout 2 | needs users : Array(User) 3 | needs oauth_client : OauthClient 4 | needs pages : Lucky::Paginator 5 | 6 | def content 7 | text "OauthClients::Users::IndexPage" 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/oauth_grants/index_page.cr: -------------------------------------------------------------------------------- 1 | struct OauthGrants::IndexPage < MainLayout 2 | needs oauth_grants : Array(OauthGrant) 3 | needs pages : Lucky::Paginator 4 | 5 | def content 6 | text "OauthGrants::IndexPage" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/oauth_grants/show_page.cr: -------------------------------------------------------------------------------- 1 | struct OauthGrants::ShowPage < MainLayout 2 | needs oauth_grant : OauthGrant 3 | 4 | def content 5 | text "OauthGrants::ShowPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/password_resets/edit_page.cr: -------------------------------------------------------------------------------- 1 | struct PasswordResets::EditPage < MainLayout 2 | needs operation : ResetPassword 3 | 4 | def content 5 | text "PasswordResets::EditPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/password_resets/index_page.cr: -------------------------------------------------------------------------------- 1 | struct PasswordResets::IndexPage < MainLayout 2 | needs password_resets : Array(PasswordReset) 3 | needs pages : Lucky::Paginator 4 | 5 | def content 6 | text "PasswordResets::IndexPage" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/password_resets/new_page.cr: -------------------------------------------------------------------------------- 1 | struct PasswordResets::NewPage < MainLayout 2 | needs operation : StartPasswordReset 3 | 4 | def content 5 | text "PasswordResets::NewPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/password_resets/show_page.cr: -------------------------------------------------------------------------------- 1 | struct PasswordResets::ShowPage < MainLayout 2 | needs password_reset : PasswordReset 3 | 4 | def content 5 | text "PasswordResets::ShowPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/regular_current_user/edit_page.cr: -------------------------------------------------------------------------------- 1 | struct RegularCurrentUser::EditPage < MainLayout 2 | needs operation : UpdateRegularCurrentUser 3 | 4 | def content 5 | text "RegularCurrentUser::EditPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/regular_current_user/new_page.cr: -------------------------------------------------------------------------------- 1 | struct RegularCurrentUser::NewPage < MainLayout 2 | needs operation : RegisterRegularCurrentUser 3 | 4 | def content 5 | text "RegularCurrentUser::NewPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/regular_current_user/show_page.cr: -------------------------------------------------------------------------------- 1 | struct RegularCurrentUser::ShowPage < MainLayout 2 | needs user : User 3 | 4 | def content 5 | text "RegularCurrentUser::ShowPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/users/bearer_logins/index_page.cr: -------------------------------------------------------------------------------- 1 | struct Users::BearerLogins::IndexPage < MainLayout 2 | needs bearer_logins : Array(BearerLogin) 3 | needs user : User 4 | needs pages : Lucky::Paginator 5 | 6 | def content 7 | text "Users::BearerLogins::IndexPage" 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/users/edit_page.cr: -------------------------------------------------------------------------------- 1 | struct Users::EditPage < MainLayout 2 | needs operation : UpdateUser 3 | 4 | def content 5 | text "Users::EditPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/users/email_confirmations/index_page.cr: -------------------------------------------------------------------------------- 1 | struct Users::EmailConfirmations::IndexPage < MainLayout 2 | needs email_confirmations : Array(EmailConfirmation) 3 | needs user : User 4 | needs pages : Lucky::Paginator 5 | 6 | def content 7 | text "Users::EmailConfirmations::IndexPage" 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/users/index_page.cr: -------------------------------------------------------------------------------- 1 | struct Users::IndexPage < MainLayout 2 | needs users : Array(User) 3 | needs pages : Lucky::Paginator 4 | 5 | def content 6 | text "Users::IndexPage" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/users/logins/index_page.cr: -------------------------------------------------------------------------------- 1 | struct Users::Logins::IndexPage < MainLayout 2 | needs logins : Array(Login) 3 | needs user : User 4 | needs pages : Lucky::Paginator 5 | 6 | def content 7 | text "Users::Logins::IndexPage" 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/users/new_page.cr: -------------------------------------------------------------------------------- 1 | struct Users::NewPage < MainLayout 2 | needs operation : RegisterUser 3 | 4 | def content 5 | text "Users::NewPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/users/oauth_clients/index_page.cr: -------------------------------------------------------------------------------- 1 | struct Users::OauthClients::IndexPage < MainLayout 2 | needs oauth_clients : Array(OauthClient) 3 | needs user : User 4 | needs pages : Lucky::Paginator 5 | 6 | def content 7 | text "Users::OauthClients::IndexPage" 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/users/oauth_grants/index_page.cr: -------------------------------------------------------------------------------- 1 | struct Users::OauthGrants::IndexPage < MainLayout 2 | needs oauth_grants : Array(OauthGrant) 3 | needs user : User 4 | needs pages : Lucky::Paginator 5 | 6 | def content 7 | text "Users::OauthGrants::IndexPage" 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/users/oauth_permissions/index_page.cr: -------------------------------------------------------------------------------- 1 | struct Users::OauthPermissions::IndexPage < MainLayout 2 | needs oauth_clients : Array(OauthClient) 3 | needs user : User 4 | needs pages : Lucky::Paginator 5 | 6 | def content 7 | text "Users::OauthPermissions::IndexPage" 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/users/password_resets/index_page.cr: -------------------------------------------------------------------------------- 1 | struct Users::PasswordResets::IndexPage < MainLayout 2 | needs password_resets : Array(PasswordReset) 3 | needs user : User 4 | needs pages : Lucky::Paginator 5 | 6 | def content 7 | text "Users::PasswordResets::IndexPage" 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /spec/support/app/src/pages/users/show_page.cr: -------------------------------------------------------------------------------- 1 | struct Users::ShowPage < MainLayout 2 | needs user : User 3 | 4 | def content 5 | text "Users::ShowPage" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/support/app/src/serializers/failure_serializer.cr: -------------------------------------------------------------------------------- 1 | struct FailureSerializer < BaseSerializer 2 | def initialize( 3 | @errors : Hash(Symbol, Array(String))? = nil, 4 | @message : String? = nil 5 | ) 6 | end 7 | 8 | private def status : Status 9 | Status::Failure 10 | end 11 | 12 | private def data_json : NamedTuple 13 | data = super 14 | 15 | @errors.try do |errors| 16 | data = data.merge({errors: errors}) unless errors.empty? 17 | end 18 | 19 | data 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /spec/support/app/tasks.cr: -------------------------------------------------------------------------------- 1 | ENV["LUCKY_TASK"] = "true" 2 | 3 | require "lucky_task" 4 | 5 | require "./src/app" 6 | # require "./tasks/**" 7 | require "./db/migrations/**" 8 | require "lucky/tasks/**" 9 | require "avram/lucky/tasks" 10 | 11 | LuckyTask::Runner.run 12 | -------------------------------------------------------------------------------- /spec/support/boot.cr: -------------------------------------------------------------------------------- 1 | require "./app/src/app" 2 | require "./api_client" 3 | require "./factories/**" 4 | -------------------------------------------------------------------------------- /spec/support/factories/bearer_login_factory.cr: -------------------------------------------------------------------------------- 1 | class BearerLoginFactory < Avram::Factory 2 | def initialize 3 | set_defaults 4 | end 5 | 6 | def token(token : String) 7 | token_digest Sha256Hash.new(token).hash 8 | end 9 | 10 | private def set_defaults 11 | name "super secret" 12 | scopes ["api.posts.index"] 13 | active_at Time.utc 14 | token "123abcdefghijklmnopqrst" 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/support/factories/email_confirmation_factory.cr: -------------------------------------------------------------------------------- 1 | class EmailConfirmationFactory < Avram::Factory 2 | def initialize 3 | set_defaults 4 | end 5 | 6 | def token(token : String) 7 | token_digest Sha256Hash.new(token).hash 8 | end 9 | 10 | private def set_defaults 11 | active_at Time.utc 12 | email "Us3R@ExampLe.tld" 13 | ip_address "1.2.3.4" 14 | success false 15 | token "123abcdefghijklmnopqrst" 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /spec/support/factories/login_factory.cr: -------------------------------------------------------------------------------- 1 | class LoginFactory < Avram::Factory 2 | def initialize 3 | set_defaults 4 | end 5 | 6 | def token(token : String) 7 | token_digest Sha256Hash.new(token).hash 8 | end 9 | 10 | private def set_defaults 11 | ip_address "1.2.3.4" 12 | active_at Time.utc 13 | token "123abcdefghijklmnopqrst" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/factories/oauth_client_factory.cr: -------------------------------------------------------------------------------- 1 | class OauthClientFactory < Avram::Factory 2 | def initialize 3 | set_defaults 4 | end 5 | 6 | def secret(secret : String) 7 | secret_digest Sha256Hash.new(secret).hash 8 | end 9 | 10 | private def set_defaults 11 | active_at Time.utc 12 | name "Awesome Client" 13 | redirect_uris ["https://example.com/oauth/callback"] 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/support/factories/password_reset_factory.cr: -------------------------------------------------------------------------------- 1 | class PasswordResetFactory < Avram::Factory 2 | def initialize 3 | set_defaults 4 | end 5 | 6 | def token(token : String) 7 | token_digest Sha256Hash.new(token).hash 8 | end 9 | 10 | private def set_defaults 11 | active_at Time.utc 12 | ip_address "1.2.3.4" 13 | success false 14 | token "123abcdefghijklmnopqrst" 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/support/factories/user_options_factory.cr: -------------------------------------------------------------------------------- 1 | class UserOptionsFactory < Avram::Factory 2 | def initialize 3 | set_defaults 4 | end 5 | 6 | private def set_defaults 7 | bearer_login_notify true 8 | login_notify true 9 | oauth_access_token_notify true 10 | password_notify true 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/charms.cr: -------------------------------------------------------------------------------- 1 | module Lucky 2 | class MessageEncryptor 3 | # Set default digest to `:sha256` 4 | def initialize( 5 | @secret : String, 6 | @cipher_algorithm = "aes-256-cbc", 7 | @digest = :sha256 8 | ) 9 | previous_def 10 | end 11 | end 12 | 13 | class MessageVerifier 14 | # Set default digest to `:sha256` 15 | def initialize(@secret : String, @digest = :sha256) 16 | previous_def 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /src/presets.cr: -------------------------------------------------------------------------------- 1 | require "./shield" 2 | require "./presets/common" 3 | require "./presets/user_options" 4 | require "./presets/**" 5 | -------------------------------------------------------------------------------- /src/presets/user_options.cr: -------------------------------------------------------------------------------- 1 | {% skip_file unless Avram::Model.all_subclasses 2 | .find(&.name.== :UserOptions.id) 3 | %} 4 | 5 | require "./common" 6 | 7 | class UserOptionsQuery < UserOptions::BaseQuery 8 | include Shield::UserOptionsQuery 9 | end 10 | 11 | class SaveUserOptions < UserOptions::SaveOperation 12 | include Shield::SaveUserOptions 13 | end 14 | -------------------------------------------------------------------------------- /src/shield.cr: -------------------------------------------------------------------------------- 1 | require "crypto/bcrypt/password" 2 | require "digest/sha1" 3 | require "digest/sha256" 4 | require "http/client" 5 | 6 | require "lucille" 7 | 8 | require "./shield/version" 9 | require "./config" 10 | require "./charms" 11 | require "./shield/operations/mixins/**" 12 | require "./shield/queries/mixins/**" 13 | require "./shield/models/mixins/**" 14 | require "./shield/utilities/mixins/**" 15 | require "./shield/**" 16 | -------------------------------------------------------------------------------- /src/shield/actions/api/bearer_logins/show.cr: -------------------------------------------------------------------------------- 1 | module Shield::Api::BearerLogins::Show 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/bearer-logins/:bearer_login_id" do 6 | # json BearerLoginSerializer.new(bearer_login: bearer_login) 7 | # end 8 | 9 | getter bearer_login : BearerLogin do 10 | BearerLoginQuery.find(bearer_login_id) 11 | end 12 | 13 | def authorize?(user : Shield::User) : Bool 14 | super || user.id == bearer_login.user_id 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /src/shield/actions/api/current_user/show.cr: -------------------------------------------------------------------------------- 1 | module Shield::Api::CurrentUser::Show 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/account" do 6 | # json UserSerializer.new(user: user) 7 | # end 8 | 9 | def user 10 | current_user_or_bearer 11 | end 12 | 13 | def authorize?(user : Shield::User) : Bool 14 | user.id == self.user.id 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /src/shield/actions/api/email_confirmation_current_user/show.cr: -------------------------------------------------------------------------------- 1 | module Shield::Api::EmailConfirmationCurrentUser::Show 2 | macro included 3 | include Shield::Api::CurrentUser::Show 4 | 5 | # get "/account" do 6 | # json UserSerializer.new(user: user) 7 | # end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/actions/api/logins/show.cr: -------------------------------------------------------------------------------- 1 | module Shield::Api::Logins::Show 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/logins/:login_id" do 6 | # json LoginSerializer.new(login: login) 7 | # end 8 | 9 | getter login : Login do 10 | LoginQuery.find(login_id) 11 | end 12 | 13 | def authorize?(user : Shield::User) : Bool 14 | super || user.id == login.user_id 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /src/shield/actions/api/mixins/email_confirmation_helpers.cr: -------------------------------------------------------------------------------- 1 | module Shield::Api::EmailConfirmationHelpers 2 | macro included 3 | include Shield::EmailConfirmationHelpers 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/actions/api/mixins/password_reset_helpers.cr: -------------------------------------------------------------------------------- 1 | module Shield::Api::PasswordResetHelpers 2 | macro included 3 | include Shield::PasswordResetHelpers 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/actions/api/oauth_clients/show.cr: -------------------------------------------------------------------------------- 1 | module Shield::Api::OauthClients::Show 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/oauth/clients/:oauth_client_id" do 6 | # json OauthClientSerializer.new(oauth_client: oauth_client) 7 | # end 8 | 9 | getter oauth_client : OauthClient do 10 | OauthClientQuery.find(oauth_client_id) 11 | end 12 | 13 | def authorize?(user : Shield::User) : Bool 14 | super || user.id == oauth_client.user_id 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /src/shield/actions/api/oauth_grants/show.cr: -------------------------------------------------------------------------------- 1 | module Shield::Api::OauthGrants::Show 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/oauth/grants/:oauth_grant_id" do 6 | # html ShowPage, oauth_grant: oauth_grant 7 | # end 8 | 9 | getter oauth_grant : OauthGrant do 10 | OauthGrantQuery.find(oauth_grant_id) 11 | end 12 | 13 | def authorize?(user : Shield::User) : Bool 14 | super || user.id == oauth_grant.user_id 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /src/shield/actions/api/users/show.cr: -------------------------------------------------------------------------------- 1 | module Shield::Api::Users::Show 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/users/:user_id" do 6 | # json UserSerializer.new(user: user) 7 | # end 8 | 9 | getter user : User do 10 | UserQuery.find(user_id) 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/shield/actions/api_action.cr: -------------------------------------------------------------------------------- 1 | module Shield::ApiAction 2 | macro included 3 | include Lucky::Paginator::BackendHelpers 4 | include Lucille::ActionHelpers 5 | 6 | include Lucille::ActionHelpers 7 | 8 | include Shield::ActionHelpers 9 | include Shield::ActionPipes 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/shield/actions/bearer_logins/show.cr: -------------------------------------------------------------------------------- 1 | module Shield::BearerLogins::Show 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/bearer-logins/:bearer_login_id" do 6 | # html ShowPage, bearer_login: bearer_login 7 | # end 8 | 9 | getter bearer_login : BearerLogin do 10 | BearerLoginQuery.find(bearer_login_id) 11 | end 12 | 13 | def authorize?(user : Shield::User) : Bool 14 | super || user.id == bearer_login.user_id 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /src/shield/actions/browser_action.cr: -------------------------------------------------------------------------------- 1 | module Shield::BrowserAction 2 | macro included 3 | include Lucky::ProtectFromForgery 4 | include Lucky::Paginator::BackendHelpers 5 | 6 | include Lucille::ActionHelpers 7 | 8 | include Shield::ActionHelpers 9 | include Shield::ActionPipes 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/shield/actions/current_login/new.cr: -------------------------------------------------------------------------------- 1 | module Shield::CurrentLogin::New 2 | macro included 3 | skip :require_logged_in 4 | 5 | # get "/login" do 6 | # operation = StartCurrentLogin.new(remote_ip: remote_ip?, session: session) 7 | # html NewPage, operation: operation 8 | # end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/shield/actions/current_user/bearer_logins/new.cr: -------------------------------------------------------------------------------- 1 | module Shield::CurrentUser::BearerLogins::New 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/account/bearer-logins/new" do 6 | # operation = CreateBearerLogin.new(user: user) 7 | # html NewPage, operation: operation 8 | # end 9 | 10 | def user 11 | current_user 12 | end 13 | 14 | def authorize?(user : Shield::User) : Bool 15 | user.id == self.user.id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /src/shield/actions/current_user/edit.cr: -------------------------------------------------------------------------------- 1 | module Shield::CurrentUser::Edit 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/account/edit" do 6 | # operation = UpdateCurrentUser.new(user, current_login: current_login?) 7 | # html EditPage, operation: operation 8 | # end 9 | 10 | def user 11 | current_user 12 | end 13 | 14 | def authorize?(user : Shield::User) : Bool 15 | user.id == self.user.id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /src/shield/actions/current_user/new.cr: -------------------------------------------------------------------------------- 1 | module Shield::CurrentUser::New 2 | macro included 3 | skip :require_logged_in 4 | 5 | # get "/account/new" do 6 | # operation = RegisterCurrentUser.new 7 | # html NewPage, operation: operation 8 | # end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/shield/actions/current_user/oauth_clients/new.cr: -------------------------------------------------------------------------------- 1 | module Shield::CurrentUser::OauthClients::New 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/account/oauth/clients/new" do 6 | # operation = RegisterOauthClient.new(user: user) 7 | # html NewPage, operation: operation 8 | # end 9 | 10 | def user 11 | current_user 12 | end 13 | 14 | def authorize?(user : Shield::User) : Bool 15 | user.id == self.user.id 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /src/shield/actions/current_user/show.cr: -------------------------------------------------------------------------------- 1 | module Shield::CurrentUser::Show 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/account" do 6 | # html ShowPage, user: user 7 | # end 8 | 9 | def user 10 | current_user 11 | end 12 | 13 | def authorize?(user : Shield::User) : Bool 14 | user.id == self.user.id 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /src/shield/actions/email_confirmation_current_user/edit.cr: -------------------------------------------------------------------------------- 1 | module Shield::EmailConfirmationCurrentUser::Edit 2 | macro included 3 | include Shield::CurrentUser::Edit 4 | 5 | # get "/account/edit" do 6 | # operation = UpdateCurrentUser.new( 7 | # user, 8 | # remote_ip: remote_ip?, 9 | # current_login: current_login? 10 | # ) 11 | # 12 | # html EditPage, operation: operation 13 | # end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/shield/actions/email_confirmation_current_user/show.cr: -------------------------------------------------------------------------------- 1 | module Shield::EmailConfirmationCurrentUser::Show 2 | macro included 3 | include Shield::CurrentUser::Show 4 | 5 | # get "/account" do 6 | # html ShowPage, user: user 7 | # end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/actions/email_confirmations/new.cr: -------------------------------------------------------------------------------- 1 | module Shield::EmailConfirmations::New 2 | macro included 3 | skip :require_logged_in 4 | 5 | # get "/email-confirmations/new" do 6 | # operation = StartEmailConfirmation.new(remote_ip: remote_ip?) 7 | # html NewPage, operation: operation 8 | # end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/shield/actions/logins/show.cr: -------------------------------------------------------------------------------- 1 | module Shield::Logins::Show 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/logins/:login_id" do 6 | # html ShowPage, login: login 7 | # end 8 | 9 | getter login : Login do 10 | LoginQuery.find(login_id) 11 | end 12 | 13 | def authorize?(user : Shield::User) : Bool 14 | super || user.id == login.user_id 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /src/shield/actions/mixins/action_pipes.cr: -------------------------------------------------------------------------------- 1 | module Shield::ActionPipes 2 | macro included 3 | after :set_previous_page_url 4 | 5 | def set_previous_page_url 6 | PageUrlSession.new(session).set(request) 7 | continue 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/shield/actions/mixins/email_confirmation_helpers.cr: -------------------------------------------------------------------------------- 1 | module Shield::EmailConfirmationHelpers 2 | macro included 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /src/shield/actions/mixins/password_reset_helpers.cr: -------------------------------------------------------------------------------- 1 | module Shield::PasswordResetHelpers 2 | macro included 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /src/shield/actions/mixins/skip_authentication_cache.cr: -------------------------------------------------------------------------------- 1 | module Shield::SkipAuthenticationCache 2 | macro included 3 | def current_user? : User? 4 | current_login?.try &.user 5 | end 6 | 7 | def current_login? : Login? 8 | LoginSession.new(session).verify 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/shield/actions/oauth_clients/show.cr: -------------------------------------------------------------------------------- 1 | module Shield::OauthClients::Show 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/oauth/clients/:oauth_client_id" do 6 | # html ShowPage, oauth_client: oauth_client 7 | # end 8 | 9 | getter oauth_client : OauthClient do 10 | OauthClientQuery.find(oauth_client_id) 11 | end 12 | 13 | def authorize?(user : Shield::User) : Bool 14 | super || user.id == oauth_client.user_id 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /src/shield/actions/oauth_grants/show.cr: -------------------------------------------------------------------------------- 1 | module Shield::OauthGrants::Show 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/oauth/grants/:oauth_grant_id" do 6 | # html ShowPage, oauth_grant: oauth_grant 7 | # end 8 | 9 | getter oauth_grant : OauthGrant do 10 | OauthGrantQuery.find(oauth_grant_id) 11 | end 12 | 13 | def authorize?(user : Shield::User) : Bool 14 | super || user.id == oauth_grant.user_id 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /src/shield/actions/password_resets/new.cr: -------------------------------------------------------------------------------- 1 | module Shield::PasswordResets::New 2 | macro included 3 | skip :require_logged_in 4 | 5 | # get "/password-resets/new" do 6 | # operation = StartPasswordReset.new(remote_ip: remote_ip?) 7 | # html NewPage, operation: operation 8 | # end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/shield/actions/password_resets/show.cr: -------------------------------------------------------------------------------- 1 | module Shield::PasswordResets::Show 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/password-resets/:password_reset_id" do 6 | # html ShowPage, password_reset: password_reset 7 | # end 8 | 9 | getter password_reset : PasswordReset do 10 | PasswordResetQuery.find(password_reset_id) 11 | end 12 | 13 | def authorize?(user : Shield::User) : Bool 14 | super || user.id == password_reset.user_id 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /src/shield/actions/users/edit.cr: -------------------------------------------------------------------------------- 1 | module Shield::Users::Edit 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/users/:user_id/edit" do 6 | # operation = UpdateUser.new(user, current_login: current_login?) 7 | # html EditPage, operation: operation 8 | # end 9 | 10 | getter user : User do 11 | UserQuery.find(user_id) 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/shield/actions/users/new.cr: -------------------------------------------------------------------------------- 1 | module Shield::Users::New 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/users/new" do 6 | # operation = RegisterUser.new 7 | # html NewPage, operation: operation 8 | # end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/shield/actions/users/show.cr: -------------------------------------------------------------------------------- 1 | module Shield::Users::Show 2 | macro included 3 | skip :require_logged_out 4 | 5 | # get "/users/:user_id" do 6 | # html ShowPage, user: user 7 | # end 8 | 9 | getter user : User do 10 | UserQuery.find(user_id) 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/shield/models/bearer_login.cr: -------------------------------------------------------------------------------- 1 | module Shield::BearerLogin 2 | macro included 3 | include Shield::BelongsToUser 4 | include Lucille::StatusColumns 5 | 6 | column name : String 7 | column scopes : Array(String) 8 | column token_digest : String 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/shield/models/email_confirmation.cr: -------------------------------------------------------------------------------- 1 | module Shield::EmailConfirmation 2 | macro included 3 | include Shield::IpAddressColumn 4 | include Shield::OptionalBelongsToUser 5 | include Lucille::SuccessStatusColumns 6 | 7 | column email : String 8 | column token_digest : String 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /src/shield/models/login.cr: -------------------------------------------------------------------------------- 1 | module Shield::Login 2 | macro included 3 | include Shield::IpAddressColumn 4 | include Shield::BelongsToUser 5 | include Lucille::StatusColumns 6 | 7 | column token_digest : String 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/models/mixins/bearer_login_user_options_columns.cr: -------------------------------------------------------------------------------- 1 | module Shield::BearerLoginUserOptionsColumns 2 | macro included 3 | column bearer_login_notify : Bool 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/models/mixins/bearer_login_user_settings.cr: -------------------------------------------------------------------------------- 1 | module Shield::BearerLoginUserSettings 2 | macro included 3 | getter? bearer_login_notify : Bool = true 4 | 5 | def bearer_login_notify 6 | bearer_login_notify? 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/models/mixins/belongs_to_oauth_client.cr: -------------------------------------------------------------------------------- 1 | module Shield::BelongsToOauthClient 2 | macro included 3 | belongs_to oauth_client : OauthClient 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/models/mixins/belongs_to_user.cr: -------------------------------------------------------------------------------- 1 | module Shield::BelongsToUser 2 | macro included 3 | belongs_to user : User 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/models/mixins/has_many_bearer_logins.cr: -------------------------------------------------------------------------------- 1 | module Shield::HasManyBearerLogins 2 | macro included 3 | has_many bearer_logins : BearerLogin 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/models/mixins/has_many_email_confirmations.cr: -------------------------------------------------------------------------------- 1 | module Shield::HasManyEmailConfirmations 2 | macro included 3 | has_many email_confirmations : EmailConfirmation 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/models/mixins/has_many_logins.cr: -------------------------------------------------------------------------------- 1 | module Shield::HasManyLogins 2 | macro included 3 | has_many logins : Login 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/models/mixins/has_many_oauth_clients.cr: -------------------------------------------------------------------------------- 1 | module Shield::HasManyOauthClients 2 | macro included 3 | has_many oauth_clients : OauthClient 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/models/mixins/has_many_oauth_grants.cr: -------------------------------------------------------------------------------- 1 | module Shield::HasManyOauthGrants 2 | macro included 3 | has_many oauth_grants : OauthGrant 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/models/mixins/has_many_password_resets.cr: -------------------------------------------------------------------------------- 1 | module Shield::HasManyPasswordResets 2 | macro included 3 | has_many password_resets : PasswordReset 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/models/mixins/has_one_user_options.cr: -------------------------------------------------------------------------------- 1 | module Shield::HasOneUserOptions 2 | macro included 3 | has_one options : UserOptions 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/models/mixins/ip_address_column.cr: -------------------------------------------------------------------------------- 1 | module Shield::IpAddressColumn 2 | macro included 3 | column ip_address : String 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/models/mixins/login_user_options_columns.cr: -------------------------------------------------------------------------------- 1 | module Shield::LoginUserOptionsColumns 2 | macro included 3 | column login_notify : Bool 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/models/mixins/login_user_settings.cr: -------------------------------------------------------------------------------- 1 | module Shield::LoginUserSettings 2 | macro included 3 | getter? login_notify : Bool = true 4 | 5 | def login_notify 6 | login_notify? 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/models/mixins/oauth_client_user_options_columns.cr: -------------------------------------------------------------------------------- 1 | module Shield::OauthClientUserOptionsColumns 2 | macro included 3 | column oauth_access_token_notify : Bool 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/models/mixins/oauth_client_user_settings.cr: -------------------------------------------------------------------------------- 1 | module Shield::OauthClientUserSettings 2 | macro included 3 | getter? oauth_access_token_notify : Bool = true 4 | 5 | def oauth_access_token_notify 6 | oauth_access_token_notify? 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/models/mixins/optional_belongs_to_oauth_client.cr: -------------------------------------------------------------------------------- 1 | module Shield::OptionalBelongsToOauthClient 2 | macro included 3 | belongs_to oauth_client : OauthClient? 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/models/mixins/optional_belongs_to_user.cr: -------------------------------------------------------------------------------- 1 | module Shield::OptionalBelongsToUser 2 | macro included 3 | belongs_to user : User? 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/models/mixins/user_settings_column.cr: -------------------------------------------------------------------------------- 1 | module Shield::UserSettingsColumn 2 | macro included 3 | column settings : UserSettings, serialize: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/models/model.cr: -------------------------------------------------------------------------------- 1 | module Shield::Model 2 | macro included 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /src/shield/models/oauth_client.cr: -------------------------------------------------------------------------------- 1 | module Shield::OauthClient 2 | macro included 3 | include Lucille::StatusColumns 4 | include Shield::BelongsToUser # Developer 5 | include Shield::HasManyBearerLogins 6 | 7 | column name : String 8 | column redirect_uris : Array(String) 9 | column secret_digest : String? 10 | 11 | def confidential? : Bool 12 | !public? 13 | end 14 | 15 | def public? : Bool 16 | secret_digest.nil? 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /src/shield/models/oauth_grant_metadata.cr: -------------------------------------------------------------------------------- 1 | module Shield::OauthGrantMetadata 2 | macro included 3 | include Lucille::JSON 4 | 5 | getter code_challenge : String? 6 | getter code_challenge_method : String = OauthGrantPkce::METHOD_PLAIN 7 | getter redirect_uri : String? 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/models/password_reset.cr: -------------------------------------------------------------------------------- 1 | module Shield::PasswordReset 2 | macro included 3 | include Shield::IpAddressColumn 4 | include Shield::BelongsToUser 5 | include Lucille::SuccessStatusColumns 6 | 7 | column token_digest : String 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/models/user.cr: -------------------------------------------------------------------------------- 1 | module Shield::User 2 | macro included 3 | # include Shield::HasManyBearerLogins 4 | # include Shield::HasManyEmailConfirmations 5 | # include Shield::HasManyLogins 6 | # include Shield::HasManyOauthClients 7 | # include Shield::HasManyOauthGrants 8 | # include Shield::HasManyPasswordResets 9 | 10 | # include Shield::HasOneUserOptions 11 | # #include Shield::UserSettingsColumn 12 | 13 | column email : String 14 | column password_digest : String 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /src/shield/models/user_options.cr: -------------------------------------------------------------------------------- 1 | module Shield::UserOptions 2 | macro included 3 | include Shield::BelongsToUser 4 | 5 | column password_notify : Bool 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/shield/operations/deactivate_oauth_client.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeactivateOauthClient # OauthClient::SaveOperation 2 | macro included 3 | include Lucille::Deactivate 4 | 5 | after_save revoke_access_tokens 6 | 7 | private def revoke_access_tokens(oauth_client : Shield::OauthClient) 8 | BearerLoginQuery.new 9 | .oauth_client_id(oauth_client.id) 10 | .is_active 11 | .update(inactive_at: Time.utc) 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/shield/operations/deactivate_user_oauth_clients.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeactivateUserOauthClients # User::SaveOperation 2 | macro included 3 | after_save deactivate_oauth_clients 4 | 5 | private def deactivate_oauth_clients(user : Shield::User) 6 | OauthClientQuery.new 7 | .user_id(user.id) 8 | .is_active 9 | .update(inactive_at: Time.utc) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/shield/operations/delete_bearer_login.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteBearerLogin # BearerLogin::DeleteOperation 2 | macro included 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /src/shield/operations/delete_email_confirmation.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteEmailConfirmation # EmailConfirmation::DeleteOperation 2 | macro included 3 | include Shield::DeleteSession 4 | 5 | private def delete_session(email_confirmation : Shield::EmailConfirmation) 6 | session.try do |session| 7 | EmailConfirmationSession.new(session).delete(email_confirmation) 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/shield/operations/delete_login.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteLogin # Login::DeleteOperation 2 | macro included 3 | include Shield::DeleteSession 4 | 5 | private def delete_session(login : Shield::Login) 6 | session.try do |session| 7 | LoginSession.new(session).delete(login) 8 | LoginIdleTimeoutSession.new(session).delete(login) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/shield/operations/delete_oauth_client.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteOauthClient # OauthClient::DeleteOperation 2 | macro included 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /src/shield/operations/delete_oauth_grant.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteOauthGrant # OauthGrant::DeleteOperation 2 | macro included 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /src/shield/operations/delete_oauth_token.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteOauthToken # Avram::Operation 2 | macro included 3 | include Shield::RevokeOauthToken 4 | 5 | private def revoke_oauth_permission 6 | @bearer_login.try do |bearer_login| 7 | bearer_login.oauth_client.try do |client| 8 | DeleteOauthPermission.update!(client, bearer_login.user) 9 | end 10 | end 11 | 12 | token.value.not_nil! 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/shield/operations/delete_password_reset.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeletePasswordReset # PasswordReset::DeleteOperation 2 | macro included 3 | include Shield::DeleteSession 4 | 5 | private def delete_session(password_reset : Shield::PasswordReset) 6 | session.try do |session| 7 | PasswordResetSession.new(session).delete(password_reset) 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/shield/operations/delete_user_email_confirmations.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteUserEmailConfirmations # User::SaveOperation 2 | macro included 3 | after_save delete_email_confirmations 4 | 5 | private def delete_email_confirmations(user : Shield::User) 6 | EmailConfirmationQuery.new.user_id(user.id).delete 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/operations/delete_user_logins.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteUserLogins # User::SaveOperation 2 | macro included 3 | needs current_login : Login? 4 | 5 | after_save delete_logins 6 | 7 | private def delete_logins(user : Shield::User) 8 | query = LoginQuery.new.user_id(user.id) 9 | current_login.try { |login| query = query.id.not.eq(login.id) } 10 | query.delete 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/shield/operations/delete_user_oauth_access_tokens.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteUserOauthAccessTokens # User::SaveOperation 2 | macro included 3 | after_save delete_access_tokens 4 | 5 | private def delete_access_tokens(user : Shield::User) 6 | BearerLoginQuery.new.user_id(user.id).oauth_client_id.is_not_nil.delete 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/operations/delete_user_oauth_clients.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteUserOauthClients # User::SaveOperation 2 | macro included 3 | after_save delete_oauth_clients 4 | 5 | private def delete_oauth_clients(user : Shield::User) 6 | OauthClientQuery.new.user_id(user.id).delete 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/operations/delete_user_oauth_grants.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteUserOauthGrants # User::SaveOperation 2 | macro included 3 | after_save delete_oauth_grants 4 | 5 | private def delete_oauth_grants(user : Shield::User) 6 | OauthGrantQuery.new.user_id(user.id).delete 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/operations/delete_user_password_resets.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteUserPasswordResets # User::SaveOperation 2 | macro included 3 | after_save delete_password_resets 4 | 5 | private def delete_password_resets(user : Shield::User) 6 | PasswordResetQuery.new.user_id(user.id).delete 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/operations/end_email_confirmation.cr: -------------------------------------------------------------------------------- 1 | module Shield::EndEmailConfirmation # EmailConfirmation::SaveOperation 2 | macro included 3 | include Lucille::Deactivate 4 | include Shield::DeleteSession 5 | 6 | private def delete_session(email_confirmation : Shield::EmailConfirmation) 7 | session.try do |session| 8 | EmailConfirmationSession.new(session).delete(email_confirmation) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/shield/operations/end_login.cr: -------------------------------------------------------------------------------- 1 | module Shield::EndLogin # Login::SaveOperation 2 | macro included 3 | include Lucille::Deactivate 4 | include Shield::DeleteSession 5 | 6 | private def delete_session(login : Shield::Login) 7 | session.try do |session| 8 | LoginSession.new(session).delete(login) 9 | LoginIdleTimeoutSession.new(session).delete(login) 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/shield/operations/end_oauth_grant.cr: -------------------------------------------------------------------------------- 1 | module Shield::EndOauthGrant # OauthGrant::SaveOperation 2 | macro included 3 | include Lucille::Deactivate 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/operations/end_password_reset.cr: -------------------------------------------------------------------------------- 1 | module Shield::EndPasswordReset # PasswordReset::SaveOperation 2 | macro included 3 | include Lucille::Deactivate 4 | include Shield::DeleteSession 5 | 6 | private def delete_session(password_reset : Shield::PasswordReset) 7 | session.try do |session| 8 | PasswordResetSession.new(session).delete(password_reset) 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/shield/operations/end_user_email_confirmations.cr: -------------------------------------------------------------------------------- 1 | module Shield::EndUserEmailConfirmations # User::SaveOperation 2 | macro included 3 | after_save end_email_confirmations 4 | 5 | private def end_email_confirmations(user : Shield::User) 6 | EmailConfirmationQuery.new 7 | .user_id(user.id) 8 | .is_active 9 | .update(inactive_at: Time.utc) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/shield/operations/end_user_logins.cr: -------------------------------------------------------------------------------- 1 | module Shield::EndUserLogins # User::SaveOperation 2 | macro included 3 | needs current_login : Login? 4 | 5 | after_save end_logins 6 | 7 | private def end_logins(user : Shield::User) 8 | query = LoginQuery.new.user_id(user.id).is_active 9 | current_login.try { |login| query = query.id.not.eq(login.id) } 10 | query.update(inactive_at: Time.utc) 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/shield/operations/end_user_oauth_grants.cr: -------------------------------------------------------------------------------- 1 | module Shield::EndUserOauthGrants # User::SaveOperation 2 | macro included 3 | after_save end_oauth_grants 4 | 5 | private def end_oauth_grants(user : Shield::User) 6 | OauthGrantQuery.new 7 | .user_id(user.id) 8 | .is_active 9 | .update(inactive_at: Time.utc) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/shield/operations/end_user_password_resets.cr: -------------------------------------------------------------------------------- 1 | module Shield::EndUserPasswordResets # User::SaveOperation 2 | macro included 3 | after_save end_password_resets 4 | 5 | private def end_password_resets(user : Shield::User) 6 | PasswordResetQuery.new 7 | .user_id(user.id) 8 | .is_active 9 | .update(inactive_at: Time.utc) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/delete_access_tokens_after_deactivate_oauth_client.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteAccessTokensAfterDeactivateOauthClient 2 | macro included 3 | after_save delete_access_tokens 4 | 5 | private def revoke_access_tokens(oauth_client : Shield::OauthClient) 6 | end 7 | 8 | private def delete_access_tokens(oauth_client : Shield::OauthClient) 9 | BearerLoginQuery.new.oauth_client_id(oauth_client.id).delete 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/delete_access_tokens_if_oauth_grant_replayed.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteAccessTokensIfOauthGrantReplayed 2 | macro included 3 | private def revoke_access_tokens 4 | oauth_grant.try do |grant| 5 | return if grant.status.active? 6 | 7 | BearerLoginQuery.new 8 | .user_id(grant.user_id) 9 | .oauth_client_id(grant.oauth_client_id) 10 | .delete 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/delete_email_confirmations_after_register_user.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteEmailConfirmationsAfterRegisterUser 2 | macro included 3 | after_save delete_email_confirmations 4 | 5 | private def end_email_confirmations(user : Shield::User) 6 | end 7 | 8 | private def delete_email_confirmations(user : Shield::User) 9 | EmailConfirmationQuery.new.email(user.email).delete 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/delete_grants_after_deactivate_oauth_client.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteGrantsAfterDeactivateOauthClient 2 | macro included 3 | after_save delete_oauth_grants 4 | 5 | private def end_oauth_grants(oauth_client : Shield::OauthClient) 6 | end 7 | 8 | private def delete_oauth_grants(oauth_client : Shield::OauthClient) 9 | OauthGrantQuery.new.oauth_client_id(oauth_client.id).delete 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/delete_grants_after_revoke_oauth_permission.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteGrantsAfterRevokeOauthPermission 2 | macro included 3 | after_save delete_oauth_grants 4 | 5 | private def revoke_oauth_grants(oauth_client : Shield::OauthClient) 6 | end 7 | 8 | private def delete_oauth_grants(oauth_client : Shield::OauthClient) 9 | OauthGrantQuery.new 10 | .user_id(user.id) 11 | .oauth_client_id(oauth_client.id) 12 | .delete 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/delete_oauth_refresh_token.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteOauthRefreshToken 2 | macro included 3 | include Shield::RevokeOauthRefreshToken 4 | 5 | private def revoke_refresh_token_permission 6 | @oauth_grant.try do |oauth_grant| 7 | DeleteOauthPermission.update!( 8 | oauth_grant.oauth_client, 9 | user: oauth_grant.user 10 | ) 11 | end 12 | 13 | token.value.not_nil! 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/delete_password_resets_after_reset_password.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeletePasswordResetsAfterResetPassword 2 | macro included 3 | after_save delete_password_resets 4 | 5 | private def end_password_resets(password_reset : Shield::PasswordReset) 6 | end 7 | 8 | private def delete_password_resets(password_reset : Shield::PasswordReset) 9 | PasswordResetQuery.new.user_id(password_reset.user_id).delete 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/delete_user_logins_on_password_change.cr: -------------------------------------------------------------------------------- 1 | module Shield::DeleteUserLoginsOnPasswordChange 2 | macro included 3 | private def end_logins(user : Shield::User) 4 | return unless password_digest.changed? 5 | 6 | DeleteLoginsEverywhere.update!(user, current_login: current_login) 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/end_oauth_grants_after_deactivate_oauth_client.cr: -------------------------------------------------------------------------------- 1 | module Shield::EndOauthAuthGrantsAfterDeactivateOauthClient 2 | macro included 3 | after_save end_oauth_grants 4 | 5 | private def end_oauth_grants(oauth_client : Shield::OauthClient) 6 | OauthGrantQuery.new 7 | .oauth_client_id(oauth_client.id) 8 | .is_active 9 | .update(inactive_at: Time.utc) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/end_user_logins_on_password_change.cr: -------------------------------------------------------------------------------- 1 | module Shield::EndUserLoginsOnPasswordChange 2 | macro included 3 | needs current_login : Login? 4 | 5 | after_save end_logins 6 | 7 | private def end_logins(user : Shield::User) 8 | return unless password_digest.changed? 9 | 10 | LogOutEverywhere.update!(user, current_login: current_login) 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/has_one_save_user_options.cr: -------------------------------------------------------------------------------- 1 | module Shield::HasOneSaveUserOptions 2 | macro included 3 | has_one save_user_options : SaveUserOptions 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/notify_bearer_login_if_set.cr: -------------------------------------------------------------------------------- 1 | module Shield::NotifyBearerLoginIfSet 2 | macro included 3 | after_commit notify_bearer_login 4 | 5 | private def notify_bearer_login(bearer_login : Shield::BearerLogin) 6 | bearer_login = BearerLoginQuery.preload_user(bearer_login) 7 | return unless bearer_login.user.settings.bearer_login_notify? 8 | 9 | BearerLoginNotificationEmail.new(self, bearer_login).deliver_later 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/notify_login.cr: -------------------------------------------------------------------------------- 1 | module Shield::NotifyLogin 2 | macro included 3 | after_commit notify_login 4 | 5 | private def notify_login(login : Shield::Login) 6 | login = LoginQuery.preload_user(login, UserQuery.new.preload_options) 7 | return unless login.user.options.login_notify 8 | 9 | LoginNotificationEmail.new(self, login).deliver_later 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/notify_login_if_set.cr: -------------------------------------------------------------------------------- 1 | module Shield::NotifyLoginIfSet 2 | macro included 3 | after_commit notify_login 4 | 5 | private def notify_login(login : Shield::Login) 6 | login = LoginQuery.preload_user(login) 7 | return unless login.user.settings.login_notify? 8 | 9 | LoginNotificationEmail.new(self, login).deliver_later 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/notify_password_change.cr: -------------------------------------------------------------------------------- 1 | module Shield::NotifyPasswordChange 2 | macro included 3 | after_commit notify_password_change 4 | 5 | private def notify_password_change(user : Shield::User) 6 | return unless password_digest.changed? 7 | 8 | user = UserQuery.preload_options(user) 9 | return unless user.options.password_notify 10 | 11 | PasswordChangeNotificationEmail.new(self, user).deliver_later 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/notify_password_change_if_set.cr: -------------------------------------------------------------------------------- 1 | module Shield::NotifyPasswordChangeIfSet 2 | macro included 3 | after_commit notify_password_change 4 | 5 | private def notify_password_change(user : Shield::User) 6 | return unless password_digest.changed? 7 | return unless user.settings.password_notify? 8 | 9 | PasswordChangeNotificationEmail.new(self, user).deliver_later 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/save_bearer_login_user_options.cr: -------------------------------------------------------------------------------- 1 | module Shield::SaveBearerLoginUserOptions 2 | macro included 3 | permit_columns :bearer_login_notify 4 | 5 | before_save do 6 | validate_bearer_login_notify_required 7 | end 8 | 9 | private def validate_bearer_login_notify_required 10 | validate_required bearer_login_notify, 11 | message: Rex.t(:"operation.error.bearer_login_notify_required") 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/save_login_user_options.cr: -------------------------------------------------------------------------------- 1 | module Shield::SaveLoginUserOptions 2 | macro included 3 | permit_columns :login_notify 4 | 5 | before_save do 6 | validate_login_notify_required 7 | end 8 | 9 | private def validate_login_notify_required 10 | validate_required login_notify, 11 | message: Rex.t(:"operation.error.login_notify_required") 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/save_oauth_client_user_options.cr: -------------------------------------------------------------------------------- 1 | module Shield::SaveOauthClientUserOptions 2 | macro included 3 | permit_columns :oauth_access_token_notify 4 | 5 | before_save do 6 | validate_oauth_access_token_notify_required 7 | end 8 | 9 | private def validate_oauth_access_token_notify_required 10 | validate_required oauth_access_token_notify, 11 | message: Rex.t(:"operation.error.oauth.access_token_notify_required") 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/send_welcome_email.cr: -------------------------------------------------------------------------------- 1 | module Shield::SendWelcomeEmail 2 | macro included 3 | before_save do 4 | send_user_welcome_email 5 | end 6 | 7 | after_commit send_welcome_email 8 | 9 | private def send_user_welcome_email 10 | return unless user_email? 11 | UserWelcomeEmail.new(self).deliver_later 12 | end 13 | 14 | private def send_welcome_email(user : Shield::User) 15 | WelcomeEmail.new(self, user).deliver_later 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/set_email_from_email_confirmation.cr: -------------------------------------------------------------------------------- 1 | module Shield::SetEmailFromEmailConfirmation 2 | macro included 3 | needs email_confirmation : EmailConfirmation 4 | 5 | before_save do 6 | set_email 7 | end 8 | 9 | private def set_email 10 | email.value = email_confirmation.email 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/set_ip_address_from_remote_address.cr: -------------------------------------------------------------------------------- 1 | module Shield::SetIpAddressFromRemoteAddress 2 | macro included 3 | needs remote_ip : Socket::IPAddress? 4 | 5 | before_save do 6 | set_ip_address 7 | end 8 | 9 | private def set_ip_address 10 | remote_ip.try { |ip| ip_address.value = ip.address } 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/set_oauth_grant_code.cr: -------------------------------------------------------------------------------- 1 | module Shield::SetOauthGrantCode 2 | macro included 3 | getter code do 4 | Random::Secure.urlsafe_base64(24) 5 | end 6 | 7 | before_save do 8 | set_code 9 | end 10 | 11 | private def set_code 12 | code_digest.value = Sha256Hash.new(code).hash 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/set_password_digest_from_password.cr: -------------------------------------------------------------------------------- 1 | module Shield::SetPasswordDigestFromPassword 2 | macro included 3 | before_save do 4 | set_password_digest 5 | end 6 | 7 | private def set_password_digest 8 | password.value.try do |value| 9 | password_digest.value = BcryptHash.new(value).hash 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/set_secret.cr: -------------------------------------------------------------------------------- 1 | module Shield::SetSecret 2 | macro included 3 | getter secret do 4 | Random::Secure.urlsafe_base64(32) 5 | end 6 | 7 | before_save do 8 | set_secret 9 | end 10 | 11 | private def set_secret 12 | secret_digest.value = Sha256Hash.new(secret).hash 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/set_token.cr: -------------------------------------------------------------------------------- 1 | module Shield::SetToken 2 | macro included 3 | getter token do 4 | Random::Secure.urlsafe_base64(32) 5 | end 6 | 7 | before_save do 8 | set_token 9 | end 10 | 11 | private def set_token 12 | token_digest.value = Sha256Hash.new(token).hash 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /src/shield/operations/mixins/set_user_email.cr: -------------------------------------------------------------------------------- 1 | module Shield::SetUserEmail 2 | macro included 3 | getter? user_email = false 4 | 5 | before_save do 6 | set_user_email 7 | end 8 | 9 | private def set_user_email 10 | email.value.try do |value| 11 | query = UserQuery.new 12 | record.try { |_record| query = query.id.not.eq(_record.id) } 13 | @user_email = query.email(value).any? 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /src/shield/operations/register_oauth_client.cr: -------------------------------------------------------------------------------- 1 | module Shield::RegisterOauthClient # OauthClient::SaveOperation 2 | macro included 3 | permit_columns :name, :redirect_uris 4 | 5 | attribute public : Bool 6 | 7 | include Lucille::Activate 8 | include Lucille::SetUserIdFromUser 9 | include Shield::SetSecret 10 | include Shield::ValidateOauthClient 11 | 12 | private def set_secret 13 | return if public.value 14 | previous_def 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /src/shield/operations/revoke_bearer_login.cr: -------------------------------------------------------------------------------- 1 | module Shield::RevokeBearerLogin # BearerLogin::SaveOperation 2 | macro included 3 | include Lucille::Deactivate 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/operations/revoke_user_oauth_access_tokens.cr: -------------------------------------------------------------------------------- 1 | module Shield::RevokeUserOauthAccessTokens # User::SaveOperation 2 | macro included 3 | after_save revoke_access_tokens 4 | 5 | private def revoke_access_tokens(user : Shield::User) 6 | BearerLoginQuery.new 7 | .user_id(user.id) 8 | .oauth_client_id.is_not_nil 9 | .is_active 10 | .update(inactive_at: Time.utc) 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /src/shield/queries/bearer_login_query.cr: -------------------------------------------------------------------------------- 1 | module Shield::BearerLoginQuery 2 | macro included 3 | include Lucille::StatusQuery 4 | 5 | def name(value : String) 6 | name.lower.eq(value.downcase) 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/queries/email_confirmation_query.cr: -------------------------------------------------------------------------------- 1 | module Shield::EmailConfirmationQuery 2 | macro included 3 | include Lucille::SuccessStatusQuery 4 | 5 | def email(value : String) 6 | email.lower.eq(value.downcase) 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/queries/login_query.cr: -------------------------------------------------------------------------------- 1 | module Shield::LoginQuery 2 | macro included 3 | include Lucille::StatusQuery 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/queries/mixins/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GrottoPress/shield/641e42087e31c2f9c6f60adbf81f51025273e826/src/shield/queries/mixins/.keep -------------------------------------------------------------------------------- /src/shield/queries/oauth_client_query.cr: -------------------------------------------------------------------------------- 1 | module Shield::OauthClientQuery 2 | macro included 3 | include Lucille::StatusQuery 4 | 5 | def is_public 6 | secret_digest.is_nil 7 | end 8 | 9 | def is_confidential 10 | secret_digest.is_not_nil 11 | end 12 | 13 | def name(value : String) 14 | name.lower.eq(value.downcase) 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /src/shield/queries/oauth_grant_query.cr: -------------------------------------------------------------------------------- 1 | module Shield::OauthGrantQuery 2 | macro included 3 | include Lucille::SuccessStatusQuery 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/queries/password_reset_query.cr: -------------------------------------------------------------------------------- 1 | module Shield::PasswordResetQuery 2 | macro included 3 | include Lucille::SuccessStatusQuery 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /src/shield/queries/user_options_query.cr: -------------------------------------------------------------------------------- 1 | module Shield::UserOptionsQuery 2 | macro included 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /src/shield/queries/user_query.cr: -------------------------------------------------------------------------------- 1 | module Shield::UserQuery 2 | macro included 3 | def email(value : String) 4 | email.lower.eq(value.downcase) 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /src/shield/utilities/login_params.cr: -------------------------------------------------------------------------------- 1 | module Shield::LoginParams 2 | macro included 3 | include Shield::LoginVerifier 4 | 5 | def initialize(@params : Avram::Paramable) 6 | end 7 | 8 | def login_id? 9 | credentials?.try(&.id) 10 | end 11 | 12 | def login_token? : String? 13 | credentials?.try(&.password) 14 | end 15 | 16 | private getter? credentials : LoginCredentials? do 17 | LoginCredentials.from_params?(@params) 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /src/shield/utilities/mixins/hash.cr: -------------------------------------------------------------------------------- 1 | module Shield::Hash 2 | abstract def hash : String 3 | abstract def verify?(digest : String) : Bool 4 | end 5 | -------------------------------------------------------------------------------- /src/shield/utilities/mixins/oauth_access_token_credentials.cr: -------------------------------------------------------------------------------- 1 | module Shield::OauthAccessTokenCredentials 2 | macro included 3 | getter? bearer_login : BearerLogin? do 4 | previous_def.try do |_bearer_login| 5 | BearerLoginQuery.preload_oauth_client(_bearer_login) 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /src/shield/utilities/mixins/param_credentials.cr: -------------------------------------------------------------------------------- 1 | module Shield::ParamCredentials 2 | macro included 3 | include Shield::Credentials 4 | 5 | def to_param : String 6 | to_s 7 | end 8 | 9 | def self.from_params(params : Avram::Paramable) : self 10 | from_params?(params).not_nil! 11 | end 12 | 13 | def self.from_params?(params : Avram::Paramable) : self? 14 | params.get?("token").try { |token| from_token?(token) } 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /src/shield/utilities/mixins/verifier.cr: -------------------------------------------------------------------------------- 1 | module Shield::Verifier 2 | macro included 3 | def verify! 4 | verify.not_nil! 5 | end 6 | 7 | def verify 8 | yield self, verify 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /src/shield/utilities/oauth_grant_params.cr: -------------------------------------------------------------------------------- 1 | module Shield::OauthGrantParams 2 | macro included 3 | include Shield::OauthGrantVerifier 4 | 5 | def initialize(@code : String?) 6 | end 7 | 8 | def oauth_grant_id? 9 | credentials?.try(&.id) 10 | end 11 | 12 | def oauth_grant_code? : String? 13 | credentials?.try(&.password) 14 | end 15 | 16 | private getter? credentials : OauthGrantCredentials? do 17 | OauthGrantCredentials.from_params?(@code) 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /src/shield/version.cr: -------------------------------------------------------------------------------- 1 | module Shield 2 | private macro set_version 3 | VERSION = {{ `shards version "#{__DIR__}"`.chomp.stringify }} 4 | end 5 | 6 | set_version 7 | end 8 | -------------------------------------------------------------------------------- /src/spec.cr: -------------------------------------------------------------------------------- 1 | require "lucille/spec" 2 | require "./shield" 3 | 4 | abstract class Lucky::BaseHTTPClient 5 | include Shield::HttpClient 6 | end 7 | --------------------------------------------------------------------------------