diff --git a/.gitignore b/.gitignore index e2aa8a6..eeff2a0 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,4 @@ .vscode .idea test_config.json +.DS_Store diff --git a/server/server.go b/server/server.go index 501b0d6..8ca0515 100644 --- a/server/server.go +++ b/server/server.go @@ -8,11 +8,14 @@ import ( "io" "io/ioutil" "log" + "math" "mime/multipart" "net/http" "net/url" + "os" "regexp" "strings" + "time" ) const ( @@ -40,6 +43,11 @@ type Server struct { Configuration } +type TokenCache struct { + AccessToken string `json:"access_token"` + ExpiresIn int `json:"expires_in"` +} + // New returns an initialized Secrets object func New(config Configuration) (*Server, error) { if config.ServerURL == "" && config.Tenant == "" || config.ServerURL != "" && config.Tenant != "" { @@ -252,12 +260,43 @@ func (s Server) uploadFile(secretId int, fileField SecretField) error { return err } +func (s *Server) setCacheAccessToken(value string, expiresIn int) error { + cache := TokenCache{} + cache.AccessToken = value + cache.ExpiresIn = (int(time.Now().Unix()) + expiresIn) - int(math.Floor(float64(expiresIn)*0.9)) + + data, _ := json.Marshal(cache) + os.Setenv("SS_AT", string(data)) + return nil +} + +func (s *Server) getCacheAccessToken() (string, bool) { + data, ok := os.LookupEnv("SS_AT") + if !ok { + os.Setenv("SS_AT", "") + return "", ok + } + cache := TokenCache{} + if err := json.Unmarshal([]byte(data), &cache); err != nil { + return "", false + } + if time.Now().Unix() < int64(cache.ExpiresIn) { + return cache.AccessToken, true + } + return "", false +} + // getAccessToken gets an OAuth2 Access Grant and returns the token // endpoint and get an accessGrant. func (s *Server) getAccessToken() (string, error) { if s.Credentials.Token != "" { return s.Credentials.Token, nil } + accessToken, found := s.getCacheAccessToken() + if found { + return accessToken, nil + } + response, err := s.checkPlatformDetails() if err != nil { log.Print("Error while checking server details:", err) @@ -292,6 +331,10 @@ func (s *Server) getAccessToken() (string, error) { log.Print("[ERROR] parsing grant response:", err) return "", err } + if err = s.setCacheAccessToken(grant.AccessToken, grant.ExpiresIn); err != nil { + log.Print("[ERROR] caching access token:", err) + return "", err + } return grant.AccessToken, nil } else { return response, nil