@@ -63,17 +63,19 @@ func NewDefaultCopyOptions() map[string]string {
6363type APIClient struct {
6464 cli * http.Client
6565
66- apiEndpoint string
67- host string
68- tenant string
69- warehouse string
70- database string
71- user string
72- password string
73- role string
74- accessTokenLoader AccessTokenLoader
75- sessionSettings map [string ]string
66+ apiEndpoint string
67+ host string
68+ tenant string
69+ warehouse string
70+ database string
71+ user string
72+ password string
73+ role string
74+ secondaryRoles * []string
75+ sessionSettings map [string ]string
76+
7677 statsTracker QueryStatsTracker
78+ accessTokenLoader AccessTokenLoader
7779
7880 WaitTimeSeconds int64
7981 MaxRowsInBuffer int64
@@ -92,6 +94,19 @@ func NewAPIClientFromConfig(cfg *Config) *APIClient {
9294 default :
9395 apiScheme = "https"
9496 }
97+
98+ // if role is set in config, we'd prefer to limit it as the only effective role,
99+ // so you could limit the privileges by setting a role with limited privileges.
100+ // however this can be overridden by executing `SET SECONDARY ROLES ALL` in the
101+ // query.
102+ // secondaryRoles now have two viable values:
103+ // - nil: means enabling ALL the granted roles of the user
104+ // - []string{}: means enabling NONE of the granted roles
105+ var secondaryRoles * []string
106+ if len (cfg .Role ) > 0 {
107+ secondaryRoles = & []string {}
108+ }
109+
95110 return & APIClient {
96111 cli : & http.Client {
97112 Timeout : cfg .Timeout ,
@@ -104,6 +119,7 @@ func NewAPIClientFromConfig(cfg *Config) *APIClient {
104119 user : cfg .User ,
105120 password : cfg .Password ,
106121 role : cfg .Role ,
122+ secondaryRoles : secondaryRoles ,
107123 accessTokenLoader : initAccessTokenLoader (cfg ),
108124 sessionSettings : cfg .Params ,
109125 statsTracker : cfg .StatsTracker ,
@@ -274,11 +290,12 @@ func (c *APIClient) getPagenationConfig() *PaginationConfig {
274290 }
275291}
276292
277- func (c * APIClient ) getSessionConfig () * SessionConfig {
278- return & SessionConfig {
279- Database : c .database ,
280- Role : c .role ,
281- Settings : c .sessionSettings ,
293+ func (c * APIClient ) getSessionState () * SessionState {
294+ return & SessionState {
295+ Database : c .database ,
296+ Role : c .role ,
297+ SecondaryRoles : c .secondaryRoles ,
298+ Settings : c .sessionSettings ,
282299 }
283300}
284301
@@ -290,7 +307,7 @@ func (c *APIClient) DoQuery(ctx context.Context, query string, args []driver.Val
290307 request := QueryRequest {
291308 SQL : q ,
292309 Pagination : c .getPagenationConfig (),
293- Session : c .getSessionConfig (),
310+ Session : c .getSessionState (),
294311 }
295312
296313 path := "/v1/query"
@@ -302,12 +319,12 @@ func (c *APIClient) DoQuery(ctx context.Context, query string, args []driver.Val
302319 if result .Error != nil {
303320 return nil , errors .Wrap (result .Error , "query error" )
304321 }
305- c .applySessionConfig (& result )
322+ c .applySessionState (& result )
306323 c .trackStats (& result )
307324 return & result , nil
308325}
309326
310- func (c * APIClient ) applySessionConfig (response * QueryResponse ) {
327+ func (c * APIClient ) applySessionState (response * QueryResponse ) {
311328 if response .Session == nil {
312329 return
313330 }
@@ -317,6 +334,7 @@ func (c *APIClient) applySessionConfig(response *QueryResponse) {
317334 if len (response .Session .Role ) > 0 {
318335 c .role = response .Session .Role
319336 }
337+ c .secondaryRoles = response .Session .SecondaryRoles
320338 if response .Session .Settings != nil {
321339 newSessionSettings := map [string ]string {}
322340 for k , v := range response .Session .Settings {
@@ -462,7 +480,7 @@ func (c *APIClient) InsertWithStage(ctx context.Context, sql string, stage *Stag
462480 request := QueryRequest {
463481 SQL : sql ,
464482 Pagination : c .getPagenationConfig (),
465- Session : c .getSessionConfig (),
483+ Session : c .getSessionState (),
466484 StageAttachment : & StageAttachmentConfig {
467485 Location : stage .String (),
468486 FileFormatOptions : fileFormatOptions ,
0 commit comments