steranko

package module
v0.20.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 14, 2024 License: Apache-2.0 Imports: 8 Imported by: 8

README

Steranko 🔐

GoDoc Version Build Status Go Report Card Codecov

Website Authentication/Authorization for Go

Steranko is an embeddable library that manages user authentication, and authorization. You can configure it at run time (or compile time) to meet your specific project needs.

To use Steranko, you have to implement two tiny interfaces in your code, then wire Steranko's handlers into your HTTP server.

s := steranko.New(userService, steranko.Conig{
    Tokens: "cookie:auth",
    PasswordSchema: `{"type":"string", "minLength":20}`
})

s.Register(echo)

DO NOT USE

This project is a work-in-progress, and should NOT be used by ANYONE, for ANY PURPOSE, under ANY CIRCUMSTANCES. It is GUARANTEED to blow up your computer, send your cat into an infinite loop, and combine your hot and cold laundry into a single cycle.

Project Goals

  • Create a configurable, open source authentication/authorization system in Go.

  • Hashed passwords using bcrypt

  • Automatically upgrade password encryption cost on signin.

  • Lock out user accounts after N failed attempts.

  • Maintain security with JWT tokens

  • Password strength checking (via JSON-Schema extensions)

  • Password vulnerability via HaveIBeenPwned API.

Possible future additions
  • Middleware tracks and blocks malicious users

    • Errors (like 404, and 500) have an associated number of points.
    • Track points per user/ip address with leaky bucket algorithm
    • Block users with a certain number of points
    • Ban users/ip addresses for repeated policy violations
    • Admin console allows tweaking of rules, reinstatement of banned accounts.
  • Identify malicious users with a (relatively) invisible CAPTCHA system

    • Track javascript events during signup (keyup, keydown, mousemove, click)
    • Track timing of events. They must not be too fast, or too consistent.
    • Something to prevent requests from being forwarded to an actual human.
    • Math problems?
    • Geolocation.

Pull Requests Welcome

Steranko is a work in progress, and will benefit from your experience reports, use cases, and contributions. If you have an idea for making this library better, send in a pull request. We're all in this together! 🔐

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CookieName added in v0.18.0

func CookieName(request *http.Request) string

CookieName returns the cookie name to use for a given request. SSL requests use __Host-Authorization, which locks the cookie to this domain Non-SSL requests use Authorization, which is not locked to a domain

func Middleware added in v0.4.2

func Middleware(factory Factory) echo.MiddlewareFunc

Middleware is a standalone middleware that works for multi-tenant environments, where you may need to use a factory to load the specific steranko settings depending on the domain being called.

Types

type Config

type Config struct {
	PasswordSchema schema.Schema `json:"passwordSchema"` // JSON-encoded schema for password validation rules.
}

type Context added in v0.3.0

type Context struct {
	echo.Context
	// contains filtered or unexported fields
}

Context extends the echo context with an authenticated JWT Token.

func (*Context) Authorization added in v0.4.0

func (ctx *Context) Authorization() (jwt.Claims, error)

Authorization retrieves the JWT token claims from the context. Values are cached so we don't re-parse the JWT cookie with mutiple calls.

type Factory added in v0.4.2

type Factory interface {

	// Steranko retrieves the correct instance to use
	// for this domain or returns an error
	Steranko(ctx echo.Context) (*Steranko, error)
}

Factory is used in multi-tenant environments to locate the steranko instance that will be used (based on the context)

type KeyService added in v0.3.0

type KeyService interface {

	// GetCurrentKey returns the current JWT key in use by the server
	GetCurrentKey() (string, any, error)

	// FindKey returns the key associated with the given JWT token.
	FindKey(*jwt.Token) (any, error)
}

KeyService is an interface that the calling application must implement in order to use Steranko. The KeyService manages the encryption keys that sign and verify JWT tokens.

type Option added in v0.16.0

type Option func(*Steranko)

func WithConfigFile added in v0.16.0

func WithConfigFile(config Config) Option

WithConfigFile loads the values from a configuration file into this Steranko instance.

func WithPasswordHasher added in v0.16.0

func WithPasswordHasher(hashers ...PasswordHasher) Option

WithPasswordHashers sets the hashing algorithm(s) to use when setting/validating passwords. The first hasher in the list is used to create new passwords. All subsequent hashers are "deprecated" and will be upgrated to the primary algorithm the next time the user signs in.

func WithPasswordRules added in v0.16.0

func WithPasswordRules(passwordRules ...PasswordRule) Option

WithPasswordRules appends the provided password rules the the list used when setting new passwords.

func WithPasswordSchema added in v0.16.0

func WithPasswordSchema(passwordSchema schema.Schema) Option

WithPasswordSchema sets the provided schema.Schema as the validation function when setting new passwords. Default is (minimum length: 8 characters)

type PasswordHasher added in v0.16.0

type PasswordHasher interface {

	// ID returns a string that uniquely identifies this plugin.
	ID() string

	// HashPassword returns a hashed value that can be (safely?) stored in a database
	HashPassword(plaintext string) (ciphertext string, error error)

	// CompareHashedValue checks that a plaintext value matches a stored ciphertext value.
	// OK returns TRUE if the values match.  Rehash returns TRUE if the hashing criteria has been updated
	// and a new hashed value should be stored in its place.
	CompareHashedPassword(plaintext string, ciphertext string) (OK bool, Rehash bool)
}

PasswordHasher handles all encryption functions for passwords.

type PasswordRule added in v0.16.0

type PasswordRule interface {

	// ID returns a string that uniquely identifies this plugin.
	ID() string

	// PasswordRuleDescription returns a map of language tags to human-readable strings that explain how the password can be used
	PasswordRuleDescription(language string) string

	// ValidatePassword returns TRUE if the password can be used in this system.  If not, it returns FALSE, and a message explaining why
	ValidatePassword(password string) (OK bool, errorMessage string)
}

PasswordRule is used to verify if a password meets the password complexity criteria for this system.

type RequestPasswordResetResponse added in v0.2.0

type RequestPasswordResetResponse struct {
}

type RequestPasswordResetTransaction

type RequestPasswordResetTransaction struct {
	Username string `json:"username" form:"userame"` // public username of the person requesting the reset.
}

type SigninResponse added in v0.2.0

type SigninResponse struct {
	Username     string
	JWT          string
	ErrorMessage string
	Error        error
}

SigninResponse includes all the information returned by Steranko after a signin request.

type SigninTransaction

type SigninTransaction struct {
	Username      string `json:"username"      form:"username"`      // public username for this person
	Password      string `json:"password"      form:"password"`      // private (hashed?) password for this person
	TwoFactorCode string `json:"twoFactorCode" form:"twoFactorCode"` // [Optional] 2FA code to send to the 2FA plugin
}

SigninTransaction includes all of the information that MUST be posted to Sterenko in order to sign in to the system.

type Steranko

type Steranko struct {
	// contains filtered or unexported fields
}

Steranko contains all required configuration information for this library.

func New

func New(userService UserService, keyService KeyService, options ...Option) *Steranko

New returns a fully initialized Steranko instance, with HandlerFuncs that support all of your user authentication and authorization needs.

func (*Steranko) ApproveRequest added in v0.4.2

func (s *Steranko) ApproveRequest(ctx echo.Context) error

ApproveRequest applies filtering rules to requests and blocks any that should not be allowed.

func (*Steranko) Authenticate

func (s *Steranko) Authenticate(username string, password string, user User) error

Authenticate verifies a username/password combination.

func (*Steranko) ComparePassword added in v0.16.0

func (s *Steranko) ComparePassword(plaintext string, hashedValue string) (bool, bool)

ComparePassword uses each

func (*Steranko) CreateCertificate added in v0.7.1

func (s *Steranko) CreateCertificate(request *http.Request, user User) (http.Cookie, error)

CreateCertificate creates a new JWT token for the provided user.

func (*Steranko) CreateJWT added in v0.16.0

func (s *Steranko) CreateJWT(claims jwt.Claims) (string, error)

CreateJWT generates a new JWT token using the specified claims.

func (*Steranko) GetAuthorization added in v0.16.0

func (s *Steranko) GetAuthorization(request *http.Request) (jwt.Claims, error)

GetAuthorization retrieves the JWT token claims from the request.

func (*Steranko) GetAuthorizationFromToken added in v0.16.0

func (s *Steranko) GetAuthorizationFromToken(tokenString string) (jwt.Claims, error)

GetAuthorizationFromToken parses a JWT token

func (*Steranko) Middleware added in v0.3.0

func (s *Steranko) Middleware(next echo.HandlerFunc) echo.HandlerFunc

Middleware wraps the original echo context with the Steranko context.

func (*Steranko) PasswordSchema

func (s *Steranko) PasswordSchema() *schema.Schema

PasswordSchema returns the schema.Schema for validating passwords

func (*Steranko) PostPasswordToken

func (s *Steranko) PostPasswordToken(ctx echo.Context) error

PostPasswordToken implements the http.HandlerFunc signature, and should be wired in to your REST API to allow users to tell the server that they forgot their password. This should initiate some way for the system to send them a one time token to create a new password.

func (*Steranko) PostPasswordUpdate

func (s *Steranko) PostPasswordUpdate(ctx echo.Context) error

PostPasswordUpdate implements the http.HandlerFunc signature, and should be wired in to your REST API to allow users to update their passwords.

func (*Steranko) PrimaryPasswordHasher added in v0.16.0

func (s *Steranko) PrimaryPasswordHasher() PasswordHasher

func (*Steranko) PushCookie added in v0.18.0

func (s *Steranko) PushCookie(ctx echo.Context, cookie http.Cookie)

PushCookie sets a new cookie to the user's context, and moves their existing cookie to be the "-backup" cookie.

func (*Steranko) SetPassword added in v0.17.0

func (s *Steranko) SetPassword(user User, plaintext string) error

func (*Steranko) SignIn added in v0.3.1

func (s *Steranko) SignIn(ctx echo.Context) error

SignIn implements the echo.HandlerFunc, and can be used directly in your REST API, or can be wrapped by your own custom function if you want to extend its functionality. If the signin is successful it automatically sets the "Authorization" cookie in the user's browser.

func (*Steranko) SignOut added in v0.3.2

func (s *Steranko) SignOut(ctx echo.Context) bool

SignOut implements the echo.HandlerFunc, and can be used directly in your REST API, or can be wrapped by your own custom function. It returns TRUE if the user had a backup cookie that has been restored, and FALSE if the user is now completely signed out.

func (*Steranko) ValidatePassword

func (s *Steranko) ValidatePassword(plaintext string) error

ValidatePassword checks a password against all system requirements

func (*Steranko) WithOptions added in v0.16.0

func (s *Steranko) WithOptions(options ...Option)

WithOptios applies the provided Option functions to this Steranko instance.

type UpdatePasswordResponse added in v0.2.0

type UpdatePasswordResponse struct {
}

type UpdatePasswordTransaction

type UpdatePasswordTransaction struct {
	Username    string `json:"username"    form:"username"`
	OldPassword string `json:"oldPassword" form:"oldPassword"`
	NewPassword string `json:"newPassword" form:"newPassword"`
}

type User

type User interface {
	GetUsername() string // Returns the username of the User
	GetPassword() string // Returns the password of the User

	SetUsername(username string)   // Sets the username of the User
	SetPassword(ciphertext string) // Sets the password of the User
	Claims() jwt.Claims            // Returns all claims (permissions) that this user has.
}

User interface wraps all of the functions that Steranko needs to authorize a user of the system. This is done so that Steranko can be retrofitted on to your existing data objects. Just implement this interface, and a CRUD service, and you're all set.

type UserService

type UserService interface {

	// New creates a newly initialized User that is ready to use
	New() User

	// Load retrieves a single User from the database
	Load(username string, user User) error

	// Save inserts/updates a single User in the database
	Save(user User, comment string) error

	// Delete removes a single User from the database
	Delete(user User, comment string) error

	// RequestPasswordReset handles the application-specific details of
	// delivering a password reset message to the user.
	RequestPasswordReset(user User) error

	// NewClaims generates an empty object that meets the jwt.Claims any
	NewClaims() jwt.Claims

	// Close cleans up any connections opened by the service.
	Close()
}

UserService wraps all of the functions that must be provided to Steranko by your application. This API matches the presto.Service API very closely, so it should be possible to wrap an existing presto service to serve Steranko, too.

Directories

Path Synopsis
plugin

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL