evcc-io/server/providerauth/providerauth.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
}