mirror of
https://github.com/volatiletech/authboss.git
synced 2025-01-10 04:17:59 +02:00
48b33b0217
- Add helper to directly merge data into a request (common use case) - Allow parsing of OAuth2PID without panic - Add oauth2.* strings to the modules list in case people want to be able to switch on which oauth2 providers are available in their views.
127 lines
3.3 KiB
Go
127 lines
3.3 KiB
Go
package authboss
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"reflect"
|
|
)
|
|
|
|
var registeredModules = make(map[string]Moduler)
|
|
|
|
// Moduler should be implemented by all the authboss modules.
|
|
type Moduler interface {
|
|
// Init the module
|
|
Init(*Authboss) error
|
|
}
|
|
|
|
// RegisterModule with the core providing all the necessary information to
|
|
// integrate into authboss.
|
|
func RegisterModule(name string, m Moduler) {
|
|
registeredModules[name] = m
|
|
}
|
|
|
|
// RegisteredModules returns a list of modules that are currently registered.
|
|
func RegisteredModules() []string {
|
|
mods := make([]string, len(registeredModules))
|
|
i := 0
|
|
for k := range registeredModules {
|
|
mods[i] = k
|
|
i++
|
|
}
|
|
|
|
return mods
|
|
}
|
|
|
|
// LoadedModules returns a list of modules that are currently loaded.
|
|
func (a *Authboss) LoadedModules() []string {
|
|
mods := make([]string, len(a.loadedModules))
|
|
i := 0
|
|
for k := range a.loadedModules {
|
|
mods[i] = k
|
|
i++
|
|
}
|
|
|
|
return mods
|
|
}
|
|
|
|
// IsLoaded checks if a specific module is loaded.
|
|
func (a *Authboss) IsLoaded(mod string) bool {
|
|
_, ok := a.loadedModules[mod]
|
|
return ok
|
|
}
|
|
|
|
// loadModule loads a particular module. It uses reflection to create a new
|
|
// instance of the module type. The original value is copied, but not deep copied
|
|
// so care should be taken to make sure most initialization happens inside the Initialize()
|
|
// method of the module.
|
|
//
|
|
// This method exists so many copies of authboss can be loaded and initialized at the same time
|
|
// if we didn't use this, then the registeredModules instances of the modules would end up used
|
|
// by the first instance of authboss.
|
|
func (a *Authboss) loadModule(name string) error {
|
|
module, ok := registeredModules[name]
|
|
if !ok {
|
|
panic("could not find module: " + name)
|
|
}
|
|
|
|
var wasPtr bool
|
|
modVal := reflect.ValueOf(module)
|
|
if modVal.Kind() == reflect.Ptr {
|
|
wasPtr = true
|
|
modVal = modVal.Elem()
|
|
}
|
|
|
|
modType := modVal.Type()
|
|
value := reflect.New(modType)
|
|
if !wasPtr {
|
|
value = value.Elem()
|
|
value.Set(modVal)
|
|
} else {
|
|
value.Elem().Set(modVal)
|
|
}
|
|
|
|
mod, ok := value.Interface().(Moduler)
|
|
a.loadedModules[name] = mod
|
|
return mod.Init(a)
|
|
}
|
|
|
|
// ModuleListMiddleware puts a map in the data that can be used
|
|
// to provide the renderer with information about which pieces of the
|
|
// views to show. The bool is extraneous, as presence in the map is the indication
|
|
// of wether or not the module is loaded.
|
|
// Data looks like:
|
|
// map[modulename] = true
|
|
//
|
|
// oauth2 providers are also listed here using the syntax:
|
|
// oauth2.google for an example. Be careful since this doesn't actually mean
|
|
// that the oauth2 module has been loaded so you should do a conditional that checks
|
|
// for both.
|
|
func ModuleListMiddleware(ab *Authboss) func(http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
var data HTMLData
|
|
|
|
ctx := r.Context()
|
|
dataIntf := ctx.Value(CTXKeyData)
|
|
if dataIntf != nil {
|
|
data = dataIntf.(HTMLData)
|
|
} else {
|
|
data = HTMLData{}
|
|
}
|
|
|
|
loaded := make(map[string]bool, len(ab.loadedModules))
|
|
for k := range ab.loadedModules {
|
|
loaded[k] = true
|
|
}
|
|
|
|
for provider := range ab.Config.Modules.OAuth2Providers {
|
|
loaded["oauth2."+provider] = true
|
|
}
|
|
|
|
data[DataModules] = loaded
|
|
r = r.WithContext(context.WithValue(ctx, CTXKeyData, data))
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
}
|