package service import ( "errors" "fmt" "io/ioutil" "os" "path" "strings" "github.com/jumpserver/koko/pkg/common" "github.com/jumpserver/koko/pkg/config" "github.com/jumpserver/koko/pkg/logger" ) var ( AccessKeyNotFound = errors.New("access key not found") AccessKeyFileNotFound = errors.New("access key file not found") AccessKeyInvalid = errors.New("access key not valid") ) type AccessKey struct { ID string Secret string Path string Value string } func (ak AccessKey) Sign() (string, string) { date := common.HTTPGMTDate() signature := common.MakeSignature(ak.Secret, date) return date, fmt.Sprintf("Sign %s:%s", ak.ID, signature) } func (ak *AccessKey) LoadAccessKeyFromStr(key string) error { if key == "" { return AccessKeyNotFound } keySlice := strings.Split(strings.TrimSpace(key), ":") if len(keySlice) != 2 { return AccessKeyInvalid } ak.ID = keySlice[0] ak.Secret = keySlice[1] return nil } func (ak *AccessKey) LoadAccessKeyFromFile(keyPath string) error { if keyPath == "" { return AccessKeyNotFound } _, err := os.Stat(keyPath) if err != nil { return AccessKeyFileNotFound } buf, err := ioutil.ReadFile(keyPath) if err != nil { msg := fmt.Sprintf("read access key failed: %s", err) return errors.New(msg) } return ak.LoadAccessKeyFromStr(string(buf)) } func (ak *AccessKey) SaveToFile() error { keyDir := path.Dir(ak.Path) if !common.FileExists(keyDir) { err := os.MkdirAll(keyDir, os.ModePerm) if err != nil { return err } } f, err := os.Create(ak.Path) defer f.Close() if err != nil { return err } _, err = f.WriteString(fmt.Sprintf("%s:%s", ak.ID, ak.Secret)) if err != nil { logger.Error(err) } return err } func (ak *AccessKey) Register(times int) error { cf := config.GetConf() name := cf.Name token := cf.BootstrapToken comment := "Coco" res := RegisterTerminal(name, token, comment) if res.Name != name { msg := "register access key failed" logger.Error(msg) os.Exit(1) } ak.ID = res.ServiceAccount.AccessKey.ID ak.Secret = res.ServiceAccount.AccessKey.Secret return nil } // LoadAccessKey 加载AccessKey用来与 Core Api 交互 func (ak *AccessKey) Load() (err error) { err = ak.LoadAccessKeyFromStr(ak.Value) if err == nil { return } err = ak.LoadAccessKeyFromFile(ak.Path) if err == nil { return } err = ak.Register(10) if err != nil { msg := "register access key failed" logger.Error(msg) return errors.New(msg) } err = ak.SaveToFile() if err != nil { msg := fmt.Sprintf("save to access key to file error: %s", err) logger.Error(msg) return errors.New(msg) } return nil }