@@ -8,12 +8,14 @@ import (
88 "context"
99 "fmt"
1010 "io"
11+ "net/http"
1112 "os"
1213 "strings"
1314 "sync"
1415 "time"
1516
1617 log "github.com/sirupsen/logrus"
18+ "github.com/sourcegraph/jsonrpc2"
1719 "github.com/spf13/cobra"
1820 "golang.org/x/sync/errgroup"
1921 "golang.org/x/xerrors"
3638 envScopeUser envScope = "user"
3739)
3840
41+ func envScopeFromString (s string ) envScope {
42+ switch s {
43+ case string (envScopeRepo ):
44+ return envScopeRepo
45+ case string (envScopeUser ):
46+ return envScopeUser
47+ default :
48+ return envScopeRepo
49+ }
50+ }
51+
3952// envCmd represents the env command
4053var envCmd = & cobra.Command {
4154 Use : "env" ,
@@ -75,8 +88,8 @@ delete environment variables with a repository pattern of */foo, foo/* or */*.
7588 if unsetEnvs {
7689 err = deleteEnvs (ctx , args )
7790 } else {
78- scopeUser := scope == string ( envScopeUser )
79- err = setEnvs (ctx , scopeUser , args )
91+ setEnvScope := envScopeFromString ( scope )
92+ err = setEnvs (ctx , setEnvScope , args )
8093 }
8194 } else {
8295 err = getEnvs (ctx )
@@ -89,14 +102,15 @@ type connectToServerResult struct {
89102 repositoryPattern string
90103 wsInfo * supervisorapi.WorkspaceInfoResponse
91104 client * serverapi.APIoverJSONRPC
105+ gitpodHost string
92106}
93107
94108type connectToServerOptions struct {
95109 supervisorClient * supervisor.SupervisorClient
96110 wsInfo * api.WorkspaceInfoResponse
97111 log * log.Entry
98112
99- setEnvScopeUser bool
113+ setEnvScope envScope
100114}
101115
102116func connectToServer (ctx context.Context , options * connectToServerOptions ) (* connectToServerResult , error ) {
@@ -133,7 +147,7 @@ func connectToServer(ctx context.Context, options *connectToServerOptions) (*con
133147 repositoryPattern := wsinfo .Repository .Owner + "/" + wsinfo .Repository .Name
134148
135149 operations := "create/get/update/delete"
136- if options != nil && options .setEnvScopeUser {
150+ if options != nil && options .setEnvScope == envScopeUser {
137151 // Updating user env vars requires a different token with a special scope
138152 repositoryPattern = "*/*"
139153 operations = "update"
@@ -166,7 +180,7 @@ func connectToServer(ctx context.Context, options *connectToServerOptions) (*con
166180 if err != nil {
167181 return nil , xerrors .Errorf ("failed connecting to server: %w" , err )
168182 }
169- return & connectToServerResult {repositoryPattern , wsinfo , client }, nil
183+ return & connectToServerResult {repositoryPattern , wsinfo , client , wsinfo . GitpodHost }, nil
170184}
171185
172186func getWorkspaceEnvs (ctx context.Context , options * connectToServerOptions ) ([]* serverapi.EnvVar , error ) {
@@ -192,9 +206,9 @@ func getEnvs(ctx context.Context) error {
192206 return nil
193207}
194208
195- func setEnvs (ctx context.Context , scopeUser bool , args []string ) error {
209+ func setEnvs (ctx context.Context , setEnvScope envScope , args []string ) error {
196210 options := connectToServerOptions {
197- setEnvScopeUser : scopeUser ,
211+ setEnvScope : setEnvScope ,
198212 }
199213 result , err := connectToServer (ctx , & options )
200214 if err != nil {
@@ -213,6 +227,11 @@ func setEnvs(ctx context.Context, scopeUser bool, args []string) error {
213227 g .Go (func () error {
214228 err = result .client .SetEnvVar (ctx , v )
215229 if err != nil {
230+ if ferr , ok := err .(* jsonrpc2.Error ); ok && ferr .Code == http .StatusForbidden && setEnvScope == envScopeUser {
231+ return fmt .Errorf ("" +
232+ "Can't automatically create Env Var `%s` for security reasons.\n " +
233+ "Please create the var manullay under %s/user/variables using Name=%s, Scope=*/*, Value=foobar" , v .Name , result .gitpodHost , v .Name )
234+ }
216235 return err
217236 }
218237 printVar (v .Name , v .Value , exportEnvs )
0 commit comments