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

68
.gitignore vendored Normal file
View File

@ -0,0 +1,68 @@
# Created by .ignore support plugin (hsz.mobi)
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff:
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
# Sensitive or high-churn files:
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
# Gradle:
.idea/**/gradle.xml
.idea/**/libraries
# Mongo Explorer plugin:
.idea/**/mongoSettings.xml
## File-based project format:
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
### Go template
# Binaries for programs and plugins
*.exe
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/
.idea/
*.iml
vendor/
glide.lock
.DS_Store
dist/
debug

32
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,32 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug",
"type": "go",
"request": "launch",
"mode": "debug",
"remotePath": "",
"port": 2345,
"host": "127.0.0.1",
"program": "${workspaceRoot}/main.go",
"env": {},
"args": [],
"showLog": true
},
{
"name": "File Debug",
"type": "go",
"request": "launch",
"mode": "debug",
"remotePath": "",
"port": 2345,
"host": "127.0.0.1",
"program": "${fileDirname}",
"env": {},
"args": [],
"showLog": true
}
]
}

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
// Place your settings in this file to overwrite default and user settings.
{
}

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() {
}

37
config.json Normal file
View File

@ -0,0 +1,37 @@
{
"account": {
"name": "domain1",
"apiKey": "52abd6fd57e511e7ac52080027658d13"
},
"central": {
"host": "127.0.0.1",
"port": 19190,
"connector": {
"handshakeTimeout": 0,
"reconnectInterval": 5,
"reconnectTryTime": 10,
"maxMessageSize": 4096,
"readBufferSize": 4096,
"writeBufferSize": 4096,
"readTimeout": 0,
"writeTimeout": 0,
"pongTimeout": 60,
"pingTimeout": 10,
"pingPeriod": 9,
"enableCompression": false
},
"proxy": {
"host": "",
"port": 9090,
"useAuth": true,
"user": "",
"password": ""
}
},
"probe": {
"key": "866f9be0333311e8b7230242ac120004"
},
"paths": {
"root": "/project/overFlow/probe"
}
}

12
config/config.go Normal file
View File

@ -0,0 +1,12 @@
package config
import (
ocpc "git.loafle.net/overflow/commons-go/probe/config"
)
type Config struct {
Account *ocpc.Account `required:"true" json:"account" yaml:"account" toml:"account"`
Central *ocpc.Central `required:"true" json:"central" yaml:"central" toml:"central"`
Probe *ocpc.Probe `required:"true" json:"probe" yaml:"probe" toml:"probe"`
Paths map[string]string `required:"true" json:"paths" yaml:"paths" toml:"paths"`
}

6
glide.yaml Normal file
View File

@ -0,0 +1,6 @@
package: git.loafle.net/overflow/probe
import:
- package: git.loafle.net/commons/logging-go
- package: git.loafle.net/commons/configuration-go
- package: git.loafle.net/commons/rpc-go
- package: git.loafle.net/commons/server-go

79
main.go Normal file
View File

@ -0,0 +1,79 @@
package main
import (
"context"
"flag"
"os"
"os/signal"
"syscall"
"time"
"git.loafle.net/commons/configuration-go"
"git.loafle.net/commons/logging-go"
occi "git.loafle.net/overflow/commons-go/core/interfaces"
ocpc "git.loafle.net/overflow/commons-go/probe/config"
"git.loafle.net/overflow/probe/auth"
"git.loafle.net/overflow/probe/config"
)
var (
configDir *string
)
func init() {
configDir = flag.String("config-dir", "./", "Config directory")
logConfigPath := flag.String("log-config", "", "logging config path")
flag.Parse()
logging.InitializeLogger(*logConfigPath)
}
func main() {
_config := &config.Config{}
configuration.SetConfigPath(*configDir)
if err := configuration.Load(_config, ocpc.ConfigFileName); nil != err {
logging.Logger().Panic(err)
}
var instance interface{}
go func() {
if ocpc.ProbeStateTypeNotAuthorized == _config.Probe.State() {
instance = &auth.Authenticator{
ConfigDir: *configDir,
Config: _config,
}
doneChan, err := instance.(occi.EndableStarter).EndableStart()
if nil != err {
logging.Logger().Panic(err)
}
err = <-doneChan
if nil != err {
logging.Logger().Panic(err)
}
}
// err := s.ListenAndServe()
// if nil != err {
// log.Printf("err: %v", err)
// }
}()
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt,
syscall.SIGKILL,
syscall.SIGSTOP,
syscall.SIGHUP,
syscall.SIGINT,
syscall.SIGTERM,
syscall.SIGQUIT)
<-interrupt
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if err := instance.(occi.Stopper).Stop(ctx); err != nil {
logging.Logger().Errorf("error: %v", err)
}
}