diff --git a/engine/api/api_routes.go b/engine/api/api_routes.go index 57274dcb7b..c6b78c05ce 100644 --- a/engine/api/api_routes.go +++ b/engine/api/api_routes.go @@ -323,7 +323,7 @@ func (api *API) InitRouter() { // Project storage r.Handle("/project/{permProjectKey}/storage/{integrationName}", Scope(sdk.AuthConsumerScopeRunExecution), r.GET(api.getArtifactsStoreHandler)) r.Handle("/project/{permProjectKey}/storage/{integrationName}/artifact/{ref}", Scope(sdk.AuthConsumerScopeRunExecution), r.POSTEXECUTE(api.postWorkflowJobArtifactHandler, MaintenanceAware())) - r.Handle("/project/{permProjectKey}/storage/{integrationName}/artifact/{ref}/url", Scope(sdk.AuthConsumerScopeRunExecution), r.POSTEXECUTE(api.postWorkflowJobArtifacWithTempURLHandler, MaintenanceAware())) + r.Handle("/project/{permProjectKey}/storage/{integrationName}/artifact/{ref}/url", Scope(sdk.AuthConsumerScopeRunExecution), r.POSTEXECUTE(api.postWorkflowJobArtifactWithTempURLHandler, MaintenanceAware())) r.Handle("/project/{permProjectKey}/storage/{integrationName}/artifact/{ref}/url/callback", Scope(sdk.AuthConsumerScopeRunExecution), r.POSTEXECUTE(api.postWorkflowJobArtifactWithTempURLCallbackHandler, MaintenanceAware())) r.Handle("/project/{permProjectKey}/storage/{integrationName}/staticfiles/{name}", Scope(sdk.AuthConsumerScopeRunExecution), r.POSTEXECUTE(api.postWorkflowJobStaticFilesHandler, MaintenanceAware())) diff --git a/engine/api/router_middleware_auth.go b/engine/api/router_middleware_auth.go index 59fe17d662..28e7a93dfc 100644 --- a/engine/api/router_middleware_auth.go +++ b/engine/api/router_middleware_auth.go @@ -82,38 +82,6 @@ func (api *API) authMiddleware(ctx context.Context, w http.ResponseWriter, req * return ctx, sdk.WithStack(sdk.ErrUnauthorized) } - // Set context values - if isService(ctx) { - ctx = context.WithValue(ctx, cdslog.AuthServiceName, apiConsumer.Service.Name) - SetTracker(w, cdslog.AuthServiceName, apiConsumer.Service.Name) - } else if isWorker(ctx) { - ctx = context.WithValue(ctx, cdslog.AuthWorkerName, apiConsumer.Worker.Name) - SetTracker(w, cdslog.AuthWorkerName, apiConsumer.Worker.Name) - } else { - ctx = context.WithValue(ctx, cdslog.AuthUsername, apiConsumer.AuthentifiedUser.Username) - SetTracker(w, cdslog.AuthUsername, apiConsumer.AuthentifiedUser.Username) - } - - ctx = context.WithValue(ctx, cdslog.AuthUserID, apiConsumer.AuthentifiedUserID) - SetTracker(w, cdslog.AuthUserID, apiConsumer.AuthentifiedUserID) - - ctx = context.WithValue(ctx, cdslog.AuthConsumerID, apiConsumer.ID) - SetTracker(w, cdslog.AuthConsumerID, apiConsumer.ID) - - session := getAuthSession(ctx) - if session != nil { - ctx = context.WithValue(ctx, cdslog.AuthSessionID, session.ID) - SetTracker(w, cdslog.AuthSessionID, session.ID) - ctx = context.WithValue(ctx, cdslog.AuthSessionIAT, session.Created.Unix()) - SetTracker(w, cdslog.AuthSessionIAT, session.Created.Unix()) - } - - claims := getAuthClaims(ctx) - if claims != nil { - ctx = context.WithValue(ctx, cdslog.AuthSessionTokenID, claims.TokenID) - SetTracker(w, cdslog.AuthSessionTokenID, claims.TokenID) - } - return ctx, nil } @@ -129,6 +97,8 @@ func (api *API) authOptionalMiddleware(ctx context.Context, w http.ResponseWrite return ctx, nil } claims := jwt.Claims.(*sdk.AuthSessionJWTClaims) + ctx = context.WithValue(ctx, cdslog.AuthSessionTokenID, claims.TokenID) + SetTracker(w, cdslog.AuthSessionTokenID, claims.TokenID) ctx = context.WithValue(ctx, contextClaims, claims) // Check for session based on jwt from context @@ -141,6 +111,10 @@ func (api *API) authOptionalMiddleware(ctx context.Context, w http.ResponseWrite log.Debug(ctx, "api.authOptionalMiddleware> no session found in context") return ctx, nil } + ctx = context.WithValue(ctx, cdslog.AuthSessionID, session.ID) + SetTracker(w, cdslog.AuthSessionID, session.ID) + ctx = context.WithValue(ctx, cdslog.AuthSessionIAT, session.Created.Unix()) + SetTracker(w, cdslog.AuthSessionIAT, session.Created.Unix()) ctx = context.WithValue(ctx, contextSession, session) // Load auth consumer for current session in database with authentified user and contacts @@ -149,6 +123,11 @@ func (api *API) authOptionalMiddleware(ctx context.Context, w http.ResponseWrite if err != nil { return ctx, sdk.NewErrorWithStack(err, sdk.ErrUnauthorized) } + ctx = context.WithValue(ctx, cdslog.AuthUserID, consumer.AuthentifiedUserID) + SetTracker(w, cdslog.AuthUserID, consumer.AuthentifiedUserID) + ctx = context.WithValue(ctx, cdslog.AuthConsumerID, consumer.ID) + SetTracker(w, cdslog.AuthConsumerID, consumer.ID) + // If the consumer is disabled, return an error if consumer.Disabled { return ctx, sdk.WrapError(sdk.ErrUnauthorized, "consumer (%s) is disabled", consumer.ID) @@ -171,18 +150,29 @@ func (api *API) authOptionalMiddleware(ctx context.Context, w http.ResponseWrite } // Add service for consumer if exists - s, err := services.LoadByConsumerID(ctx, api.mustDB(), consumer.ID) + consumer.Service, err = services.LoadByConsumerID(ctx, api.mustDB(), consumer.ID) if err != nil && !sdk.ErrorIs(err, sdk.ErrNotFound) { return ctx, err } - consumer.Service = s + if consumer.Service != nil { + ctx = context.WithValue(ctx, cdslog.AuthServiceName, consumer.Service.Name) + SetTracker(w, cdslog.AuthServiceName, consumer.Service.Name) + } // Add worker for consumer if exists - wk, err := worker.LoadByConsumerID(ctx, api.mustDB(), consumer.ID) + consumer.Worker, err = worker.LoadByConsumerID(ctx, api.mustDB(), consumer.ID) if err != nil && !sdk.ErrorIs(err, sdk.ErrNotFound) { return ctx, err } - consumer.Worker = wk + if consumer.Worker != nil { + ctx = context.WithValue(ctx, cdslog.AuthWorkerName, consumer.Worker.Name) + SetTracker(w, cdslog.AuthWorkerName, consumer.Worker.Name) + } + + if consumer.Service == nil && consumer.Worker == nil { + ctx = context.WithValue(ctx, cdslog.AuthUsername, consumer.AuthentifiedUser.Username) + SetTracker(w, cdslog.AuthUsername, consumer.AuthentifiedUser.Username) + } ctx = context.WithValue(ctx, contextConsumer, consumer) diff --git a/engine/api/workflow_application.go b/engine/api/workflow_application.go index 9bd0b15fb3..14bb0af0ed 100644 --- a/engine/api/workflow_application.go +++ b/engine/api/workflow_application.go @@ -19,6 +19,10 @@ import ( func (api *API) releaseApplicationWorkflowHandler() service.Handler { return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { + if isWorker := isWorker(ctx); !isWorker { + return sdk.WithStack(sdk.ErrForbidden) + } + vars := mux.Vars(r) key := vars["key"] name := vars["permWorkflowName"] diff --git a/engine/api/workflow_queue_storage.go b/engine/api/workflow_queue_storage.go index 2330691ead..da561b98fe 100644 --- a/engine/api/workflow_queue_storage.go +++ b/engine/api/workflow_queue_storage.go @@ -314,7 +314,7 @@ func (api *API) postWorkflowJobArtifactWithTempURLCallbackHandler() service.Hand // DEPRECATED // TODO: remove this code after CDN would be mandatory -func (api *API) postWorkflowJobArtifacWithTempURLHandler() service.Handler { +func (api *API) postWorkflowJobArtifactWithTempURLHandler() service.Handler { return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { if isWorker := isWorker(ctx); !isWorker { return sdk.WithStack(sdk.ErrForbidden) diff --git a/engine/worker/internal/requirement.go b/engine/worker/internal/requirement.go index a6802e7b1c..77ce4f0b10 100644 --- a/engine/worker/internal/requirement.go +++ b/engine/worker/internal/requirement.go @@ -226,7 +226,7 @@ func checkPluginBinary(ctx context.Context, w *CurrentWorker, p sdk.GRPCPlugin) } } if binary == nil { - return fmt.Errorf("%s %s not supported by this plugin", currentOS, currentARCH) + return fmt.Errorf("%s/%s not supported by plugin %s", currentOS, currentARCH, p.Name) } // then check plugin requirements diff --git a/engine/worker/internal/run.go b/engine/worker/internal/run.go index 20015e2e10..cdfae551ba 100644 --- a/engine/worker/internal/run.go +++ b/engine/worker/internal/run.go @@ -788,6 +788,8 @@ func (w *CurrentWorker) executeHooksSetup(ctx context.Context, basedir afero.Fs, setupDir = filepath.Join(absPath, filepath.Base(setupDir)) + workerEnv := w.Environ() + err := filepath.Walk(setupDir, func(filepath string, info os.FileInfo, err error) error { if err != nil { return err @@ -798,7 +800,7 @@ func (w *CurrentWorker) executeHooksSetup(ctx context.Context, basedir afero.Fs, str := fmt.Sprintf("source %s ; echo '<<>>' ; env", filepath) cmd := exec.Command("bash", "-c", str) - cmd.Env = w.Environ() + cmd.Env = workerEnv bs, err := cmd.CombinedOutput() if err != nil { return errors.WithStack(err) @@ -806,7 +808,6 @@ func (w *CurrentWorker) executeHooksSetup(ctx context.Context, basedir afero.Fs, s := bufio.NewScanner(bytes.NewReader(bs)) start := false for s.Scan() { - fmt.Println(s.Text()) if s.Text() == "<<>>" { start = true } else if start { @@ -814,8 +815,7 @@ func (w *CurrentWorker) executeHooksSetup(ctx context.Context, basedir afero.Fs, if len(kv) == 2 { k := kv[0] v := kv[1] - if !sdk.IsInArray(k+"="+v, os.Environ()) { - log.Info(ctx, "env variable from hook %q: %s=%s", filepath, k, v) + if !sdk.IsInArray(k+"="+v, workerEnv) { result[k] = v } } @@ -824,7 +824,7 @@ func (w *CurrentWorker) executeHooksSetup(ctx context.Context, basedir afero.Fs, return nil }) w.currentJob.envFromHooks = result - return err + return errors.WithStack(err) } func (w *CurrentWorker) executeHooksTeardown(ctx context.Context, basedir afero.Fs, workingDir string) error { diff --git a/sdk/messages.go b/sdk/messages.go index 4d3439aa8b..62447438bb 100644 --- a/sdk/messages.go +++ b/sdk/messages.go @@ -69,7 +69,7 @@ var ( MsgSpawnInfoJobTaken = &Message{"MsgSpawnInfoJobTaken", trad{FR: "Le job %s a été pris par le worker %s", EN: "Job %s has been taken by worker %s"}, nil, RunInfoTypInfo} MsgSpawnInfoJobTakenWorkerVersion = &Message{"MsgSpawnInfoJobTakenWorkerVersion", trad{FR: "Worker %s version:%s os:%s arch:%s", EN: "Worker %s version:%s os:%s arch:%s"}, nil, RunInfoTypInfo} MsgSpawnInfoWorkerForJob = &Message{"MsgSpawnInfoWorkerForJob", trad{FR: "Ce worker %s a été créé pour lancer ce job", EN: "This worker %s was created to take this action"}, nil, RunInfoTypInfo} - MsgSpawnInfoWorkerForJobError = &Message{"MsgSpawnInfoWorkerForJobError", trad{FR: "⚠ Ce worker %s a été créé pour lancer ce job, mais ne possède pas tous les pré-requis. Vérifiez que les prérequis suivants:%s", EN: "⚠ This worker %s was created to take this action, but does not have all prerequisites. Please verify the following prerequisites:%s"}, nil, RunInfoTypeError} + MsgSpawnInfoWorkerForJobError = &Message{"MsgSpawnInfoWorkerForJobError", trad{FR: "⚠ Ce worker %s a été créé pour lancer ce job, mais ne possède pas tous les pré-requis. Vérifiez que les prérequis suivants: %s", EN: "⚠ This worker %s was created to take this action, but does not have all prerequisites. Please verify the following prerequisites: %s"}, nil, RunInfoTypeError} MsgSpawnInfoJobError = &Message{"MsgSpawnInfoJobError", trad{FR: "⚠ Impossible de lancer ce job : %s", EN: "⚠ Unable to run this job: %s"}, nil, RunInfoTypInfo} MsgWorkflowStarting = &Message{"MsgWorkflowStarting", trad{FR: "Le workflow %s#%s a été démarré", EN: "Workflow %s#%s has been started"}, nil, RunInfoTypInfo} MsgWorkflowError = &Message{"MsgWorkflowError", trad{FR: "⚠ Une erreur est survenue: %v", EN: "⚠ An error has occurred: %v"}, nil, RunInfoTypeError}