64 lines
1.5 KiB
Go
64 lines
1.5 KiB
Go
package providerauth
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"io"
|
|
"net/http"
|
|
|
|
"github.com/evcc-io/evcc/api"
|
|
"github.com/evcc-io/evcc/util"
|
|
"github.com/gorilla/mux"
|
|
)
|
|
|
|
var instance *Handler
|
|
|
|
type AuthProvider struct {
|
|
ID string `json:"id"`
|
|
Authenticated bool `json:"authenticated"`
|
|
}
|
|
|
|
func init() {
|
|
var secret [16]byte
|
|
if _, err := io.ReadFull(rand.Reader, secret[:]); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
instance = &Handler{
|
|
log: util.NewLogger("providerauth"),
|
|
secret: secret[:],
|
|
providers: make(map[string]api.AuthProvider),
|
|
states: make(map[string]string),
|
|
updateC: make(chan string, 1),
|
|
}
|
|
}
|
|
|
|
// Setup connects the redirect handler to the router and registers the callback channel
|
|
func Setup(router *mux.Router, paramC chan<- util.Param) {
|
|
// callback?code=...&state=...
|
|
router.Methods(http.MethodGet).Path("/callback").HandlerFunc(instance.handleCallback)
|
|
// login?id=...
|
|
router.Methods(http.MethodGet).Path("/login").HandlerFunc(instance.handleLogin)
|
|
// logout?id=...
|
|
router.Methods(http.MethodGet).Path("/logout").HandlerFunc(instance.handleLogout)
|
|
|
|
go instance.run(paramC)
|
|
}
|
|
|
|
// Register registers a specific AuthProvider by name
|
|
// The returned online channel is used to asynchronously update authorization status
|
|
func Register(name string, handler api.AuthProvider) (chan<- bool, error) {
|
|
updateC, err := instance.register(name, handler)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
onlineC := make(chan bool)
|
|
|
|
go func() {
|
|
for range onlineC {
|
|
updateC <- name
|
|
}
|
|
}()
|
|
|
|
return onlineC, nil
|
|
}
|