overflow_probes/auth/auth.go
crusader fa3eb473fb ing
2017-10-13 14:32:34 +09:00

174 lines
3.5 KiB
Go

package auth
import (
"context"
"fmt"
"net/http"
"path"
lfcc "git.loafle.net/commons_go/config"
"git.loafle.net/commons_go/logging"
"git.loafle.net/overflow/overflow_probes/central/api/module"
"git.loafle.net/overflow/overflow_probes/central/client"
"git.loafle.net/overflow/overflow_probes/commons"
"git.loafle.net/overflow/overflow_probes/config"
opuu "git.loafle.net/overflow/overflow_probes/util/url"
)
const (
noAuthEntryPoint = "/auth"
)
type Auther interface {
commons.EndableStarter
commons.Shutdowner
}
type auth struct {
centralClient client.Client
entryURL string
noAuthConfigPath string
noAuthConfig config.NoAuthProbeConfig
endded chan<- error
shutdown chan bool
accepted chan bool
denied chan error
}
func New() (Auther, error) {
var err error
a := &auth{
shutdown: make(chan bool),
accepted: make(chan bool),
denied: make(chan error),
}
if a.entryURL, err = opuu.Join(config.CFG.Central.URL, noAuthEntryPoint); nil != err {
return nil, err
}
a.noAuthConfigPath = path.Join(*config.ConfigDir, config.NoAuthProbeConfigFileName)
conf := lfcc.New()
if lfcc.Exists(a.noAuthConfigPath) {
if err = conf.Load(&a.noAuthConfig, a.noAuthConfigPath); nil != err {
return nil, fmt.Errorf("Auth: Loading of NoAuth config file[%s] failed error[%v]", a.noAuthConfigPath, err)
}
}
a.centralClient = client.New()
a.centralClient.OnNotify(a.onNotify)
return a, nil
}
func (a *auth) EndableStart(endded chan<- error) error {
a.endded = endded
return a.start()
}
func (a *auth) start() error {
if nil != a.noAuthConfig.DenyDate {
return fmt.Errorf("Cannot start because this probe have been denied from overFlow at %s", a.noAuthConfig.DenyDate.String())
}
var err error
if nil != a.noAuthConfig.TempKey && "" != *a.noAuthConfig.TempKey {
err = a.serveConnect(*a.noAuthConfig.TempKey)
} else {
err = a.serveRegistration()
}
if nil != err {
return err
}
a.listen()
return nil
}
func (a *auth) listen() {
go func() {
for {
select {
case <-a.shutdown:
break
case <-a.accepted:
a.stop(nil)
break
case err := <-a.denied:
a.stop(err)
break
}
}
}()
}
func (a *auth) serveRegistration() error {
var err error
header := http.Header{}
var enc string
if enc, err = getRegistHeader(); nil != err {
return err
}
header[module.NoAuthProbeHeader_NoAuthRegist] = []string{enc}
var res *http.Response
if res, err = a.centralClient.Dial(a.entryURL, header); nil != err {
return err
}
tempKey := res.Header.Get(module.NoAuthProbeHeader_SetNoAuthID)
a.noAuthConfig.TempKey = &tempKey
if err = lfcc.Save(a.noAuthConfig, a.noAuthConfigPath, true); nil != err {
return err
}
return nil
}
func (a *auth) serveConnect(noAuthTempKey string) error {
var err error
header := http.Header{}
header[module.NoAuthProbeHeader_NoAuthID] = []string{noAuthTempKey}
var res *http.Response
if res, err = a.centralClient.Dial(a.entryURL, header); nil != err {
return err
}
logging.Logger.Debug(fmt.Sprintf("Auth: Connect HTTP Status[%s]", res.Status))
return nil
}
func (a *auth) Shutdown(ctx context.Context) error {
for {
a.stop(fmt.Errorf("Shutdown"))
select {
case <-ctx.Done():
return ctx.Err()
}
}
}
func (a *auth) stop(err error) {
defer close(a.shutdown)
a.shutdown <- true
close(a.accepted)
close(a.denied)
ctx := context.Background()
if err := a.centralClient.Shutdown(ctx); nil != err {
logging.Logger.Error(fmt.Sprintf("Client of Central: %v", err))
}
a.endded <- err
}