package auth import ( "context" "fmt" "path" "sync" "git.loafle.net/commons/configuration-go" cdr "git.loafle.net/commons/di-go/registry" logging "git.loafle.net/commons/logging-go" crc "git.loafle.net/commons/rpc-go/client" occa "git.loafle.net/overflow/commons-go/core/annotation" ocnc "git.loafle.net/overflow/commons-go/noauthprobe/config" "git.loafle.net/overflow/probe/client/central" "git.loafle.net/overflow/probe/config" // For service _ "git.loafle.net/overflow/probe/auth/service" ) type Authenticator struct { Config *config.Config ConfigDir string authConfig ocnc.Auth stopChan chan struct{} stopWg sync.WaitGroup } func (a *Authenticator) EndableStart() (<-chan error, error) { if a.stopChan != nil { return nil, fmt.Errorf("authenticator already running. Stop it before starting it again") } authConfigPath := path.Join(a.ConfigDir, ocnc.ConfigFileName) conf := configuration.New() if configuration.Exists(authConfigPath) { if err := conf.Load(&a.authConfig, authConfigPath); nil != err { logging.Logger().Errorf("%s %v", err) return nil, fmt.Errorf("loading of auth config file[%s] failed", authConfigPath) } } if nil != a.authConfig.DeniedDate { return nil, fmt.Errorf("cannot start because this probe have been denied from overFlow at %s", a.authConfig.DeniedDate.String()) } cdr.RegisterResource("AuthConfig", &a.authConfig) authDoneChan := make(chan error) cdr.RegisterResource("AuthDoneChan", authDoneChan) services, err := cdr.GetInstancesByAnnotationType(occa.RPCServiceAnnotationType) if nil != err { return nil, err } client, err := central.NewAuth(a.HandleTempKey, services) if nil != err { return nil, err } endChan := make(chan error) a.stopChan = make(chan struct{}) a.stopWg.Add(1) go a.handleAuthenticator(client, authDoneChan, endChan) return endChan, nil } func (a *Authenticator) Stop(ctx context.Context) error { if a.stopChan == nil { return fmt.Errorf("Authenticator: must be started before stopping it") } close(a.stopChan) a.stopWg.Wait() a.stopChan = nil return nil } func (a *Authenticator) logHeader() string { return "Authenticator:" } func (a *Authenticator) HandleTempKey(tempKey string) { logging.Logger().Infof("%s registered by central", a.logHeader()) a.authConfig.TempKey = &tempKey if err := configuration.Save(a.authConfig, path.Join(a.ConfigDir, ocnc.ConfigFileName), true); nil != err { logging.Logger().Errorf("%s %v", a.logHeader(), err) return } } func (a *Authenticator) handleAuthenticator(client *crc.Client, authDoneChan chan error, endChan chan<- error) { var err error defer func() { if nil != client { err = client.Stop(context.Background()) } a.stopWg.Done() endChan <- err }() if err = client.Start(); nil != err { logging.Logger().Error(err) return } for { select { case err = <-authDoneChan: return case <-a.stopChan: return } } }