This commit is contained in:
crusader
2018-04-12 20:54:56 +09:00
commit 0fc01915ae
11 changed files with 614 additions and 0 deletions

211
auth/authenticator.go Normal file
View File

@@ -0,0 +1,211 @@
package auth
import (
"context"
"fmt"
"net/http"
"path"
"sync"
"time"
"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"
crpj "git.loafle.net/commons/rpc-go/protocol/json"
crr "git.loafle.net/commons/rpc-go/registry"
csswc "git.loafle.net/commons/server-go/socket/web/client"
occa "git.loafle.net/overflow/commons-go/core/annotation"
ocnc "git.loafle.net/overflow/commons-go/noauthprobe/config"
ocncc "git.loafle.net/overflow/commons-go/noauthprobe/constants"
ocpc "git.loafle.net/overflow/commons-go/probe/config"
"git.loafle.net/overflow/probe/auth/info"
_ "git.loafle.net/overflow/probe/auth/service"
"git.loafle.net/overflow/probe/config"
)
type Authenticator struct {
Config *config.Config
ConfigDir string
authConfig ocnc.Auth
client *crc.Client
accpetedChan chan string
deniedChan chan struct{}
tempKeyChan chan string
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.DenyDate {
return nil, fmt.Errorf("cannot start because this probe have been denied from overFlow at %s", a.authConfig.DenyDate.String())
}
a.accpetedChan = make(chan string, 1)
a.deniedChan = make(chan struct{}, 1)
a.tempKeyChan = make(chan string, 1)
if err := a.initClient(); nil != err {
return nil, err
}
if err := a.client.Start(); nil != err {
return nil, err
}
endChan := make(chan error)
a.stopChan = make(chan struct{})
a.stopWg.Add(1)
go a.handleAuthenticator(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) initService() (crr.RPCInvoker, error) {
cdr.RegisterResource("AccpetedChan", a.accpetedChan)
cdr.RegisterResource("DeniedChan", a.deniedChan)
services, err := cdr.GetInstancesByAnnotationType(occa.RPCServiceAnnotationType)
if nil != err {
return nil, err
}
rpcRegistry := crr.NewRPCRegistry()
rpcRegistry.RegisterServices(services...)
return rpcRegistry, nil
}
func (a *Authenticator) initClient() error {
_connector := a.Config.Central.Connector.Clone()
connector := _connector.(*csswc.Connectors)
header := make(map[string][]string)
switch a.authConfig.State() {
case ocnc.AuthStateTypeRegisterd:
header[ocncc.HTTPRequestHeaderKey_NoAuthProbe_Method] = []string{ocncc.HTTPRequestHeaderValue_NoAuthProbe_Method_Connect}
header[ocncc.HTTPRequestHeaderKey_NoAuthProbe_TempProbeKey] = []string{*a.authConfig.TempKey}
default:
rh, err := info.GetRegistHeader(a.Config.Account.APIKey)
if nil != err {
return err
}
header[ocncc.HTTPRequestHeaderKey_NoAuthProbe_Method] = []string{ocncc.HTTPRequestHeaderValue_NoAuthProbe_Method_Regist}
header[ocncc.HTTPRequestHeaderKey_NoAuthProbe_Info] = []string{rh}
}
centralURL := fmt.Sprintf("ws://%s:%d", a.Config.Central.Host, a.Config.Central.Port)
connector.URL = path.Join(centralURL, ocncc.HTTPEntry_Auth)
connector.RequestHeader = header
connector.ResponseHandler = func(res *http.Response) {
switch a.authConfig.State() {
case ocnc.AuthStateTypeNotRegisterd:
tempProbeKey := res.Header.Get(ocncc.HTTPResponseHeaderKey_NoAuthProbe_SetTempProbeKey)
a.tempKeyChan <- tempProbeKey
default:
}
}
rpcInvoker, err := a.initService()
if nil != err {
return err
}
codec := crpj.NewClientCodec()
a.client = &crc.Client{
Connector: connector,
Codec: codec,
RPCInvoker: rpcInvoker,
Name: "Authenticator",
}
return nil
}
func (a *Authenticator) handleAuthenticator(endChan chan<- error) {
var err error
defer func() {
if nil != a.client {
err = a.client.Stop(context.Background())
}
a.stopWg.Done()
endChan <- err
}()
for {
select {
case probeKey, ok := <-a.accpetedChan:
if !ok {
return
}
logging.Logger().Infof("%s accepted by central", a.logHeader())
a.Config.Probe.Key = &probeKey
err = configuration.Save(a.Config, path.Join(a.ConfigDir, ocpc.ConfigFileName), true)
if nil != err {
logging.Logger().Errorf("%s %v", a.logHeader(), err)
}
return
case _, ok := <-a.deniedChan:
if !ok {
return
}
logging.Logger().Infof("%s denied by central", a.logHeader())
n := time.Now()
a.authConfig.DenyDate = &n
err = configuration.Save(a.authConfig, path.Join(a.ConfigDir, ocnc.ConfigFileName), true)
if nil != err {
logging.Logger().Errorf("%s %v", a.logHeader(), err)
}
return
case tempKey, ok := <-a.tempKeyChan:
if !ok {
return
}
logging.Logger().Infof("%s registered by central", a.logHeader())
a.authConfig.TempKey = &tempKey
err = configuration.Save(a.authConfig, path.Join(a.ConfigDir, ocnc.ConfigFileName), true)
if nil != err {
logging.Logger().Errorf("%s %v", a.logHeader(), err)
return
}
case <-a.stopChan:
return
}
}
}

121
auth/info/info.go Normal file
View File

@@ -0,0 +1,121 @@
package info
import (
"bytes"
"encoding/base64"
"encoding/json"
"errors"
"net"
"git.loafle.net/commons/util-go/net/gateway"
noauthprobeM "git.loafle.net/overflow/commons-go/noauthprobe/model"
"github.com/shirou/gopsutil/host"
)
func GetRegistHeader(apiKey string) (string, error) {
var err error
nap := noauthprobeM.NoAuthProbe{
APIKey: apiKey,
}
var napd *noauthprobeM.NoAuthProbeDescription
if napd, err = getDescription(); nil != err {
return "", err
}
var buf []byte
if buf, err = json.Marshal(napd); nil != err {
return "", err
}
nap.Description = string(buf)
if buf, err = json.Marshal(nap); nil != err {
return "", err
}
enc := base64.StdEncoding.EncodeToString(buf)
return enc, nil
}
func getDescription() (*noauthprobeM.NoAuthProbeDescription, error) {
var err error
napd := &noauthprobeM.NoAuthProbeDescription{}
if napd.Host, err = getHost(); nil != err {
return nil, err
}
if napd.Network, err = getNetwork(); nil != err {
return nil, err
}
return napd, nil
}
func getHost() (*noauthprobeM.NoAuthProbeDescriptionHost, error) {
if i, err := host.Info(); nil == err {
h := &noauthprobeM.NoAuthProbeDescriptionHost{}
h.Name = i.Hostname
h.OS = i.OS
h.Platform = i.Platform
h.PlatformFamily = i.PlatformFamily
h.KernelVersion = i.KernelVersion
h.HostID = i.HostID
return h, nil
} else {
return nil, err
}
}
func getNetwork() (*noauthprobeM.NoAuthProbeDescriptionNetwork, error) {
var ip net.IP
var iface string
var err error
if ip, iface, err = gateway.DiscoverGateway(); nil != err {
return nil, err
}
interfaces, err := net.Interfaces()
if err != nil {
return nil, err
}
idx := -1
for _idx, i := range interfaces {
if i.Name == iface {
idx = _idx
break
}
}
if -1 == idx {
return nil, errors.New("Interface of gateway is not exist")
}
n := &noauthprobeM.NoAuthProbeDescriptionNetwork{}
i := interfaces[idx]
n.Name = i.Name
n.MacAddress = i.HardwareAddr.String()
n.Gateway = ip.String()
if addrs, err := i.Addrs(); nil == err {
var buffer bytes.Buffer
for _idx, a := range addrs {
if 0 < _idx {
buffer.WriteString("|")
}
buffer.WriteString(a.String())
}
n.Address = buffer.String()
} else {
return nil, err
}
return n, nil
}

View File

@@ -0,0 +1,32 @@
package service
import (
"reflect"
cda "git.loafle.net/commons/di-go/annotation"
cdr "git.loafle.net/commons/di-go/registry"
_ "git.loafle.net/overflow/commons-go/core/annotation"
)
var AuthServiceType = reflect.TypeOf((*AuthService)(nil))
func init() {
cdr.RegisterType(AuthServiceType)
}
type AuthService struct {
cda.TypeAnnotation `annotation:"@overflow:RPCService()"`
AcceptedChan chan<- string
DeniedChan chan<- struct{}
}
func (as *AuthService) Accept(probeKey string) error {
as.AcceptedChan <- probeKey
return nil
}
func (as *AuthService) Deny() error {
as.DeniedChan <- struct{}{}
return nil
}

13
auth/service/service.go Normal file
View File

@@ -0,0 +1,13 @@
package service
func InitPackage() {
}
func StartPackage() {
}
func StopPackage() {
}
func DestroyPackage() {
}