diff options
Diffstat (limited to 'src/actions/mixins/api')
-rw-r--r-- | src/actions/mixins/api/auth/helpers.cr | 28 | ||||
-rw-r--r-- | src/actions/mixins/api/auth/require_auth_token.cr | 34 | ||||
-rw-r--r-- | src/actions/mixins/api/auth/skip_require_auth_token.cr | 10 |
3 files changed, 72 insertions, 0 deletions
diff --git a/src/actions/mixins/api/auth/helpers.cr b/src/actions/mixins/api/auth/helpers.cr new file mode 100644 index 0000000..6b51cb5 --- /dev/null +++ b/src/actions/mixins/api/auth/helpers.cr @@ -0,0 +1,28 @@ +module Api::Auth::Helpers + # The 'memoize' macro makes sure only one query is issued to find the user + memoize def current_user? : User? + auth_token.try do |value| + user_from_auth_token(value) + end + end + + private def auth_token : String? + bearer_token || token_param + end + + private def bearer_token : String? + context.request.headers["Authorization"]? + .try(&.gsub("Bearer", "")) + .try(&.strip) + end + + private def token_param : String? + params.get?(:auth_token) + end + + private def user_from_auth_token(token : String) : User? + UserToken.decode_user_id(token).try do |user_id| + UserQuery.new.id(user_id).first? + end + end +end diff --git a/src/actions/mixins/api/auth/require_auth_token.cr b/src/actions/mixins/api/auth/require_auth_token.cr new file mode 100644 index 0000000..e018638 --- /dev/null +++ b/src/actions/mixins/api/auth/require_auth_token.cr @@ -0,0 +1,34 @@ +module Api::Auth::RequireAuthToken + macro included + before require_auth_token + end + + private def require_auth_token + if current_user? + continue + else + json auth_error_json, 401 + end + end + + private def auth_error_json + ErrorSerializer.new( + message: "Not authenticated.", + details: auth_error_details + ) + end + + private def auth_error_details : String + if auth_token + "The provided authentication token was incorrect." + else + "An authentication token is required. Please include a token in an 'auth_token' param or 'Authorization' header." + end + end + + # Tells the compiler that the current_user is not nil since we have checked + # that the user is signed in + private def current_user : User + current_user?.as(User) + end +end diff --git a/src/actions/mixins/api/auth/skip_require_auth_token.cr b/src/actions/mixins/api/auth/skip_require_auth_token.cr new file mode 100644 index 0000000..68098cf --- /dev/null +++ b/src/actions/mixins/api/auth/skip_require_auth_token.cr @@ -0,0 +1,10 @@ +module Api::Auth::SkipRequireAuthToken + macro included + skip require_auth_token + end + + # Since sign in is not required, current_user might be nil + def current_user : User? + current_user? + end +end |