reblocks-auth

2023-10-21

A system to add an authentication to the Reblocks based web-site.

Upstream URL

github.com/40ants/reblocks-auth

Author

Alexander Artemenko <svetlyak.40wt@gmail.com>

License

Unlicense
README

reblocks-auth - A system to add an authentication to the Reblocks based web-site.

REBLOCKS-AUTH ASDF System Details

Reblocks-auth is a system for adding authentication for your Reblocks application. It allows users to login using multiple ways. Right now GitHub is only supported but the list will be extended.

This system uses Mito as a storage to store data about users and their data from service providers. Each user has a unique nickname and an optional email. Also, one or more identity providers can be bound to each user account.

Installation

You can install this library from Quicklisp, but you want to receive updates quickly, then install it from Ultralisp.org:

(ql-dist:install-dist "http://dist.ultralisp.org/"
                      :prompt nil)
(ql:quickload :reblocks-auth)

Example App

I've made an example application to demonstrate how does reblocks-auth system work. To start this example application, run this code in the REPL:

(asdf:load-system :reblocks-auth-example)

(reblocks-auth-example/server:start :port 8080)

When you'll open the http://localhost:8080/ you will see this simple website:

Usage

This system provides a way for user authentifications. Each user is represented in the database using reblocks-auth/models:user model user can be bound to one or more "social profiles" - reblocks-auth/models:social-profile. For example, if user logged in via GitHub, then database will store one "user" record and one "social-profile" record. Each social profile can hold additional information in it's metadata slot.

To use this system, you have to define two routes which will be responsible for login and logout. On each route you have to render either reblocks-auth:login-processor or reblocks-auth:logout-processor widgets.

Usually you can define your routes like this (reblocks-navigation-widget:defroutes is used here):

(defroutes routes
    ("/" (make-page-frame
          (make-landing-page)))
  ("/login"
   (make-page-frame
    (reblocks-auth:make-login-processor)))
  ("/logout"
   (make-page-frame
    (reblocks-auth:make-logout-processor))))

This code will render a set up buttons to login through enabled service providers. Enabled service providers are listed in reblocks-auth:*enabled-services* variable.

Login processor does two things:

Logout processor renders a "logout" button and when user clicks on it, removes user from the current session.

API

REBLOCKS-AUTH/AUTH

package reblocks-auth/auth

Generics

generic-function reblocks-auth/auth:authenticate service &rest params &key code

Called when user had authenticated in the service and returned to our site.

All GET arguments are collected into a plist and passed as params.

Should return two values a user and a flag denotifing if user was just created.

REBLOCKS-AUTH/BUTTON

package reblocks-auth/button

Generics

generic-function reblocks-auth/button:render service &key retpath

Renders a button for given service. Service should be a keyword like :github or :facebook.

REBLOCKS-AUTH/CONDITIONS

package reblocks-auth/conditions

Classes

UNABLE-TO-AUTHENTICATE

condition reblocks-auth/conditions:unable-to-authenticate ()

Readers

reader reblocks-auth/conditions:get-message (unable-to-authenticate) (:message)

reader reblocks-auth/conditions:get-reason (unable-to-authenticate) (:reason = 'nil)

REBLOCKS-AUTH/CORE

package reblocks-auth/core

Classes

LOGIN-PROCESSOR

class reblocks-auth/core:login-processor (widget)

This widget should be rendered to process user's login.

LOGOUT-PROCESSOR

class reblocks-auth/core:logout-processor (widget)

This widget should be rendered to process user's logout.

Functions

function reblocks-auth/core:make-login-processor

function reblocks-auth/core:make-logout-processor

function reblocks-auth/core:render-buttons &key retpath

Renders a row of buttons for enabled service providers.

Optionally you can specify RETPATH argument with an URI to return user after login.

Variables

variable reblocks-auth/core:*enabled-services* (:github)

Set this variable to limit a services available to login through.

variable reblocks-auth/core:*login-hooks* nil

Append a funcallable handlers which accept single argument - logged user.

REBLOCKS-AUTH/ERRORS

package reblocks-auth/errors

Classes

NICKNAME-IS-NOT-AVAILABLE

condition reblocks-auth/errors:nickname-is-not-available (error)

Signalled when there is already a user with given nickname.

REBLOCKS-AUTH/GITHUB

package reblocks-auth/github

Functions

function reblocks-auth/github:get-scopes

Returns current user's scopes.

function reblocks-auth/github:get-token

Returns current user's GitHub token.

function reblocks-auth/github:render-button &KEY (CLASS "button small") (SCOPES *DEFAULT-SCOPES*) (TEXT "Grant permissions") (RETPATH (GET-URI))

Renders a button to request more scopes.

Variables

variable reblocks-auth/github:*client-id* nil

OAuth client id

variable reblocks-auth/github:*default-scopes* ("user:email")

A listo of default scopes to request from GitHub.

variable reblocks-auth/github:*secret* nil

OAuth secret. It might be a string or secret-values:secret-value.

REBLOCKS-AUTH/MODELS

package reblocks-auth/models

Classes

SOCIAL-PROFILE

class reblocks-auth/models:social-profile (serial-pk-mixin dao-class record-timestamps-mixin)

Represents a User's link to a social service. User can be bound to multiple social services.

Readers

reader reblocks-auth/models:profile-metadata (social-profile) (:metadata :params)

reader reblocks-auth/models:profile-service (social-profile) (:service)

reader reblocks-auth/models:profile-service-user-id (social-profile) (:service-user-id)

[reader] reblocks-auth/models:profile-user (social-profile) (:user)

A user instance, bound to the social-profile.

Accessors

accessor reblocks-auth/models:profile-metadata (social-profile) (:metadata :params)

USER

class reblocks-auth/models:user (serial-pk-mixin dao-class record-timestamps-mixin)

This class stores basic information about user - it's nickname and email. Additional information is stored inside social-profile instances.

Readers

reader reblocks-auth/models:get-email (user) (:email = nil)

reader reblocks-auth/models:get-nickname (user) (:nickname)

Functions

function reblocks-auth/models:anonymous-p user

function reblocks-auth/models:change-email user email

function reblocks-auth/models:change-nickname new-nickname

Changes nickname of the current user.

function reblocks-auth/models:create-social-user service service-user-id &rest metadata &key email

function reblocks-auth/models:find-social-user service service-user-id

function reblocks-auth/models:get-all-users

function reblocks-auth/models:get-current-user

Returns current user or NIL.

function reblocks-auth/models:get-user-by-email email

Returns a user with given email.

function reblocks-auth/models:get-user-by-nickname nickname

Returns a user with given email.

function reblocks-auth/models:user-social-profiles user

Returns a list of social profiles, bound to the user.

REBLOCKS-AUTH/PROVIDERS/EMAIL/MAILGUN

package reblocks-auth/providers/email/mailgun

Macros

macro reblocks-auth/providers/email/mailgun:define-code-sender NAME (FROM-EMAIL URL-VAR &KEY (SUBJECT "Authentication code")) &BODY HTML-TEMPLATE-BODY

REBLOCKS-AUTH/PROVIDERS/EMAIL/MODELS

package reblocks-auth/providers/email/models

Classes

REGISTRATION-CODE

class reblocks-auth/providers/email/models:registration-code (serial-pk-mixin dao-class record-timestamps-mixin)

This model stores a code sent to an email for signup or log in.

Readers

reader reblocks-auth/providers/email/models:registration-code (registration-code) (:code)

reader reblocks-auth/providers/email/models:registration-email (registration-code) (:email)

User's email.

reader reblocks-auth/providers/email/models:valid-until (registration-code) (:valid-until)

Expiration time.

Variables

variable reblocks-auth/providers/email/models:*send-code-callback* -unbound-

Set this variable to a function of one argument of class registration-code. It should send a registration code using template, suitable for your website.

Roadmap

  • Add support for authentication by a link sent to the email.

  • Add ability to bind multiple service providers to a single user.


[generated by 40ANTS-DOC]

Dependencies (29)

Dependents (1)

  • GitHub
  • Quicklisp