@@ -19,7 +19,9 @@ package config
1919
2020import (
2121 "fmt"
22+ "strings"
2223
24+ "github.com/arduino/go-paths-helper"
2325 "github.com/sirupsen/logrus"
2426 "github.com/spf13/viper"
2527)
@@ -38,8 +40,8 @@ const (
3840 CredentialsFilename = "arduino-cloud-credentials"
3941)
4042
41- // SetDefaultCredentials sets the default credentials values.
42- func SetDefaultCredentials (settings * viper.Viper ) {
43+ // SetEmptyCredentials sets the default credentials values to empty strings .
44+ func SetEmptyCredentials (settings * viper.Viper ) {
4345 // Client ID
4446 settings .SetDefault ("client" , "" )
4547 // Secret
@@ -77,89 +79,110 @@ func (c *Credentials) IsEmpty() bool {
7779 return len (c .Client ) == 0 && len (c .Secret ) == 0
7880}
7981
80- // RetrieveCredentials looks for credentials in
82+ // FindCredentials looks for credentials in
8183// environment variables or in credentials file.
82- // Returns error if no credentials are found.
83- func RetrieveCredentials () (* Credentials , error ) {
84+ // Returns the source of found credentials (env or filepath).
85+ // Returns an error if credentials are not found
86+ // specifying paths where the credentials are searched.
87+ func FindCredentials () (source string , err error ) {
8488 // Credentials extracted from environment has highest priority
8589 logrus .Info ("Looking for credentials in environment variables" )
8690 c , err := fromEnv ()
8791 if err != nil {
88- return nil , fmt .Errorf ("reading credentials from environment variables: %w" , err )
92+ return "" , fmt .Errorf ("looking for credentials in environment variables: %w" , err )
8993 }
90- // Return credentials only if found
91- if c != nil {
92- logrus .Info ("Credentials found in environment variables" )
93- return c , nil
94+ if ! c .IsEmpty () {
95+ logrus .Infof ("Credentials found in environment variables with prefix '%s'" , EnvPrefix )
96+ return "environment variables" , nil
9497 }
9598
9699 logrus .Info ("Looking for credentials in file system" )
97- c , err = fromFile ( )
100+ path , found , err := searchConfigFile ( CredentialsFilename )
98101 if err != nil {
99- return nil , fmt .Errorf ("reading credentials from file : %w" , err )
102+ return "" , fmt .Errorf ("looking for credentials files : %w" , err )
100103 }
101- if c != nil {
102- return c , nil
104+ if found {
105+ return path , nil
103106 }
104107
105- return nil , fmt .Errorf (
108+ return "" , fmt .Errorf (
106109 "credentials have not been found neither in environment variables " +
107110 "nor in the current directory, its parents or in arduino15" ,
108111 )
109112}
110113
111- // fromFile looks for a credentials file.
112- // If a credentials file is not found, it returns nil credentials without raising errors.
113- // If invalid credentials file is found, it returns an error.
114- func fromFile () (* Credentials , error ) {
115- // Looks for a credentials file
116- configDir , err := searchConfigDir (CredentialsFilename )
114+ // RetrieveCredentials retrieves credentials from
115+ // environment variables or credentials file.
116+ // Returns error if credentials are not found or
117+ // if found credentials are invalid.
118+ func RetrieveCredentials () (cred * Credentials , err error ) {
119+ // Credentials extracted from environment has highest priority
120+ logrus .Info ("Looking for credentials in environment variables" )
121+ cred , err = fromEnv ()
122+ if err != nil {
123+ return nil , fmt .Errorf ("reading credentials from environment variables: %w" , err )
124+ }
125+ // Returns credentials if found in env
126+ if ! cred .IsEmpty () {
127+ // Returns error if credentials are found but are not valid
128+ if err := cred .Validate (); err != nil {
129+ return nil , fmt .Errorf (
130+ "credentials retrieved from environment variables with prefix '%s' are not valid: %w" , EnvPrefix , err ,
131+ )
132+ }
133+ logrus .Infof ("Credentials found in environment variables with prefix '%s'" , EnvPrefix )
134+ return cred , nil
135+ }
136+
137+ logrus .Info ("Looking for credentials in file system" )
138+ filepath , found , err := searchConfigFile (CredentialsFilename )
117139 if err != nil {
118140 return nil , fmt .Errorf ("can't get credentials directory: %w" , err )
119141 }
120- // Return nil credentials if no config file is found
121- if configDir == nil {
122- return nil , nil
142+ // Returns credentials if found in a file
143+ if found {
144+ if cred , err = fromFile (filepath ); err != nil {
145+ return nil , fmt .Errorf ("reading credentials from file %s: %w" , filepath , err )
146+ }
147+ // Returns error if credentials are found but are not valid
148+ if err := cred .Validate (); err != nil {
149+ return nil , fmt .Errorf (
150+ "credentials retrieved from file %s are not valid: %w" , filepath , err ,
151+ )
152+ }
153+ return cred , nil
123154 }
124155
156+ return nil , fmt .Errorf (
157+ "credentials have not been found neither in environment variables " +
158+ "nor in the current directory, its parents or in arduino15" ,
159+ )
160+ }
161+
162+ // fromFile retrieves credentials from a credentials file.
163+ // Returns error if credentials are not found or cannot be fetched.
164+ func fromFile (filepath string ) (* Credentials , error ) {
125165 v := viper .New ()
126- v .SetConfigName ( CredentialsFilename )
127- v .AddConfigPath ( * configDir )
128- err = v .ReadInConfig ()
166+ v .SetConfigFile ( filepath )
167+ v .SetConfigType ( strings . TrimLeft ( paths . New ( filepath ). Ext (), "." ) )
168+ err : = v .ReadInConfig ()
129169 if err != nil {
130- err = fmt .Errorf (
131- "credentials file found at %s but cannot read its content: %w" ,
132- * configDir ,
133- err ,
134- )
135- return nil , err
170+ return nil , fmt .Errorf ("cannot read credentials file: %w" , err )
136171 }
137172
138173 cred := & Credentials {}
139174 err = v .Unmarshal (cred )
140175 if err != nil {
141- return nil , fmt .Errorf (
142- "credentials file found at %s but cannot unmarshal it: %w" ,
143- * configDir ,
144- err ,
145- )
146- }
147- if err = cred .Validate (); err != nil {
148- return nil , fmt .Errorf (
149- "credentials file found at %s but is not valid: %w" ,
150- * configDir ,
151- err ,
152- )
176+ return nil , fmt .Errorf ("cannot unmarshal credentials file: %w" , err )
153177 }
154178 return cred , nil
155179}
156180
157- // fromEnv looks for credentials in environment variables.
158- // If credentials are not found, it returns nil credentials without raising errors.
159- // If invalid credentials are found, it returns an error.
181+ // fromEnv retrieves credentials from environment variables.
182+ // Returns empty credentials if not found.
160183func fromEnv () (* Credentials , error ) {
161184 v := viper .New ()
162- SetDefaultCredentials (v )
185+ SetEmptyCredentials (v )
163186 v .SetEnvPrefix (EnvPrefix )
164187 v .AutomaticEnv ()
165188
@@ -168,17 +191,5 @@ func fromEnv() (*Credentials, error) {
168191 if err != nil {
169192 return nil , fmt .Errorf ("cannot unmarshal credentials from environment variables: %w" , err )
170193 }
171-
172- if cred .IsEmpty () {
173- return nil , nil
174- }
175-
176- if err = cred .Validate (); err != nil {
177- return nil , fmt .Errorf (
178- "credentials retrieved from environment variables with prefix '%s' are not valid: %w" ,
179- EnvPrefix ,
180- err ,
181- )
182- }
183194 return cred , nil
184195}
0 commit comments