[tilo][service] Read auth token from Context

We should always supply all request-related values in the context
object, since this is a standard Go pattern.

IN-699 #comment

Change-Id: I4b5d6def5882a99a72ba4735f636465dee285c7b
diff --git a/tilo/resultstore/service/context.go b/tilo/resultstore/service/context.go
index 2da3c82..234f0e1 100644
--- a/tilo/resultstore/service/context.go
+++ b/tilo/resultstore/service/context.go
@@ -13,21 +13,32 @@
 const (
 	// TestUUIDContextKey references a UUID to use for testing.
 	TestUUIDContextKey = fxctx.ContextKey("test-uuid")
+
+	// AuthTokenKey references the auth token to use in ResultStore requests.
+	AuthTokenKey = fxctx.ContextKey("auth-token")
 )
 
-// GetTestUUID gets the test UUID, if present. Errors if the value is present or cannot be
+// TestUUID gets the test UUID, if present. Errors if the value is missing or cannot be
 // read from the Context.
-func GetTestUUID(ctx context.Context) (string, error) {
+func TestUUID(ctx context.Context) (string, error) {
 	var uuid string
-
-	if err := fxctx.Get(ctx, TestUUIDContextKey, &uuid); err != nil {
-		return "", err
-	}
-
-	return uuid, nil
+	err := fxctx.Get(ctx, TestUUIDContextKey, &uuid)
+	return uuid, err
 }
 
 // SetTestUUID sets a UUID to use for testing.
 func SetTestUUID(ctx context.Context, uuid string) (context.Context, error) {
 	return fxctx.Set(ctx, TestUUIDContextKey, uuid)
 }
+
+// AuthToken gets the auth token to use in ResultStore requests.
+func AuthToken(ctx context.Context) (string, error) {
+	var token string
+	err := fxctx.Get(ctx, AuthTokenKey, &token)
+	return token, err
+}
+
+// SetAuthToken sets the auth token to use in ResultStore requests.
+func SetAuthToken(ctx context.Context, value string) (context.Context, error) {
+	return fxctx.Set(ctx, AuthTokenKey, value)
+}
diff --git a/tilo/resultstore/service/service.go b/tilo/resultstore/service/service.go
index 3ece686..1e4c4b1 100644
--- a/tilo/resultstore/service/service.go
+++ b/tilo/resultstore/service/service.go
@@ -20,6 +20,9 @@
 // Service methods generate UUIDs for certain proto.Message fields.  If the provided
 // Context contains a non-empty string value for TestUUIDContextKey, that value will be
 // used instead.
+//
+// Service methods require an Invocation's auth token to be set in the provided Context.
+// This can be done by calling: `SetAuthToken(ctx, "auth-token")`.
 type Service interface {
 	// CreateInvocation creates an Invocation in ResultStore. This must be called before
 	// any other "Create" methods, since all resources belong to an Invocation.
@@ -66,14 +69,13 @@
 // New creates a new Service.  Set useFakeUUIDs to true to use fake UUIDs for
 // testing.  authToken is the authorization token to use for the invocation.  The same
 // token must be used in all requests to modify a single invocation.
-func New(client api.ResultStoreUploadClient, authToken string) Service {
-	return &service{client: client, authToken: authToken}
+func New(client api.ResultStoreUploadClient) Service {
+	return &service{client: client}
 }
 
 // The default Service implementation.
 type service struct {
-	authToken string
-	client    api.ResultStoreUploadClient
+	client api.ResultStoreUploadClient
 }
 
 // uuid generates an RFC-4122 compliant Version 4 UUID.  If the provided Context contains
@@ -81,7 +83,7 @@
 // there was an error when reading the UUID from the context, a message is logged
 // describing the error and a new UUID is generated.
 func (s *service) uuid(ctx context.Context) string {
-	value, err := GetTestUUID(ctx)
+	value, err := TestUUID(ctx)
 
 	if err != nil {
 		log.Println(err)
@@ -96,9 +98,14 @@
 }
 
 func (s *service) CreateInvocation(ctx context.Context, invocation *Invocation) (*Invocation, error) {
+	authToken, err := AuthToken(ctx)
+	if err != nil {
+		return nil, err
+	}
+
 	res, err := s.client.CreateInvocation(ctx, &api.CreateInvocationRequest{
 		RequestId:          s.uuid(ctx),
-		AuthorizationToken: s.authToken,
+		AuthorizationToken: authToken,
 		InvocationId:       s.uuid(ctx),
 		Invocation:         invocation.ToResultStoreInvocation(),
 	})
@@ -111,9 +118,14 @@
 }
 
 func (s *service) CreateConfiguration(ctx context.Context, config *Configuration, invocationName string) (*Configuration, error) {
+	authToken, err := AuthToken(ctx)
+	if err != nil {
+		return nil, err
+	}
+
 	res, err := s.client.CreateConfiguration(ctx, &api.CreateConfigurationRequest{
 		RequestId:          s.uuid(ctx),
-		AuthorizationToken: s.authToken,
+		AuthorizationToken: authToken,
 		Parent:             invocationName,
 		ConfigId:           config.ID,
 		Configuration:      config.ToResultStoreConfiguration(),
@@ -127,9 +139,14 @@
 }
 
 func (s *service) CreateTarget(ctx context.Context, target *Target, invocationName string) (*Target, error) {
+	authToken, err := AuthToken(ctx)
+	if err != nil {
+		return nil, err
+	}
+
 	res, err := s.client.CreateTarget(ctx, &api.CreateTargetRequest{
 		RequestId:          s.uuid(ctx),
-		AuthorizationToken: s.authToken,
+		AuthorizationToken: authToken,
 		Parent:             invocationName,
 		TargetId:           target.ID,
 		Target:             target.ToResultStoreTarget(),
@@ -143,8 +160,13 @@
 }
 
 func (s *service) CreateConfiguredTarget(ctx context.Context, configTarget *ConfiguredTarget, targetName string) (*ConfiguredTarget, error) {
+	authToken, err := AuthToken(ctx)
+	if err != nil {
+		return nil, err
+	}
+
 	res, err := s.client.CreateConfiguredTarget(ctx, &api.CreateConfiguredTargetRequest{
-		AuthorizationToken: s.authToken,
+		AuthorizationToken: authToken,
 		RequestId:          s.uuid(ctx),
 		Parent:             targetName,
 		ConfigId:           configTarget.ConfigID,
@@ -160,8 +182,13 @@
 }
 
 func (s *service) CreateTestAction(ctx context.Context, action *TestAction, configTargetName string) (*TestAction, error) {
+	authToken, err := AuthToken(ctx)
+	if err != nil {
+		return nil, err
+	}
+
 	res, err := s.client.CreateAction(ctx, &api.CreateActionRequest{
-		AuthorizationToken: s.authToken,
+		AuthorizationToken: authToken,
 		RequestId:          s.uuid(ctx),
 		Parent:             configTargetName,
 		ActionId:           action.ID,
@@ -177,8 +204,13 @@
 
 // UpdateTestAction updates the duration and status of a previously started TestAction.
 func (s *service) UpdateTestAction(ctx context.Context, action *TestAction) (*TestAction, error) {
+	authToken, err := AuthToken(ctx)
+	if err != nil {
+		return nil, err
+	}
+
 	res, err := s.client.UpdateAction(ctx, &api.UpdateActionRequest{
-		AuthorizationToken: s.authToken,
+		AuthorizationToken: authToken,
 		Action:             action.ToResultStoreAction(),
 		UpdateMask: &field_mask.FieldMask{
 			Paths: []string{"timing.duration", "status_attributes"},
@@ -195,8 +227,13 @@
 // UpdateConfiguredTarget updates the duration and status of a previously started
 // UpdateConfigured.
 func (s *service) UpdateConfiguredTarget(ctx context.Context, configTarget *ConfiguredTarget) (*ConfiguredTarget, error) {
+	authToken, err := AuthToken(ctx)
+	if err != nil {
+		return nil, err
+	}
+
 	res, err := s.client.UpdateConfiguredTarget(ctx, &api.UpdateConfiguredTargetRequest{
-		AuthorizationToken: s.authToken,
+		AuthorizationToken: authToken,
 		ConfiguredTarget:   configTarget.ToResultStoreConfiguredTarget(),
 		UpdateMask: &field_mask.FieldMask{
 			Paths: []string{"timing.duration", "status_attributes"},
@@ -212,8 +249,13 @@
 
 // UpdateTarget updates the duration and status of a previously started Target.
 func (s *service) UpdateTarget(ctx context.Context, target *Target) (*Target, error) {
+	authToken, err := AuthToken(ctx)
+	if err != nil {
+		return nil, err
+	}
+
 	res, err := s.client.UpdateTarget(ctx, &api.UpdateTargetRequest{
-		AuthorizationToken: s.authToken,
+		AuthorizationToken: authToken,
 		UpdateMask: &field_mask.FieldMask{
 			Paths: []string{"timing.duration", "status_attributes"},
 		},
@@ -229,8 +271,13 @@
 
 // UpdateInvocation updates the duration and status of a previously started Invocation.
 func (s *service) UpdateInvocation(ctx context.Context, invocation *Invocation) (*Invocation, error) {
+	authToken, err := AuthToken(ctx)
+	if err != nil {
+		return nil, err
+	}
+
 	res, err := s.client.UpdateInvocation(ctx, &api.UpdateInvocationRequest{
-		AuthorizationToken: s.authToken,
+		AuthorizationToken: authToken,
 		UpdateMask: &field_mask.FieldMask{
 			Paths: []string{"timing.duration", "status_attributes"},
 		},
@@ -246,8 +293,13 @@
 
 // FinishConfiguredTarget closes a ConfiguredTarget for editing.
 func (s *service) FinishConfiguredTarget(ctx context.Context, name string) error {
-	_, err := s.client.FinishConfiguredTarget(ctx, &api.FinishConfiguredTargetRequest{
-		AuthorizationToken: s.authToken,
+	authToken, err := AuthToken(ctx)
+	if err != nil {
+		return err
+	}
+
+	_, err = s.client.FinishConfiguredTarget(ctx, &api.FinishConfiguredTargetRequest{
+		AuthorizationToken: authToken,
 		Name:               name,
 	})
 	return err
@@ -255,8 +307,13 @@
 
 // FinishTarget closes a Target for editing.
 func (s *service) FinishTarget(ctx context.Context, name string) error {
-	_, err := s.client.FinishTarget(ctx, &api.FinishTargetRequest{
-		AuthorizationToken: s.authToken,
+	authToken, err := AuthToken(ctx)
+	if err != nil {
+		return err
+	}
+
+	_, err = s.client.FinishTarget(ctx, &api.FinishTargetRequest{
+		AuthorizationToken: authToken,
 		Name:               name,
 	})
 	return err
@@ -264,8 +321,13 @@
 
 // FinishInvocation closes an Invocation for editing.
 func (s *service) FinishInvocation(ctx context.Context, name string) error {
-	_, err := s.client.FinishInvocation(ctx, &api.FinishInvocationRequest{
-		AuthorizationToken: s.authToken,
+	authToken, err := AuthToken(ctx)
+	if err != nil {
+		return err
+	}
+
+	_, err = s.client.FinishInvocation(ctx, &api.FinishInvocationRequest{
+		AuthorizationToken: authToken,
 		Name:               name,
 	})
 	return err
diff --git a/tilo/resultstore/service/service_test.go b/tilo/resultstore/service/service_test.go
index 80d7d25..f18f0a8 100644
--- a/tilo/resultstore/service/service_test.go
+++ b/tilo/resultstore/service/service_test.go
@@ -25,7 +25,7 @@
 	// The specific values of the UUIDs are not important for these tests. We just want to
 	// verify that the service sets some value other than the empty string, so we just use
 	// the same UUID everywhere.
-	TestUUID = "uuid"
+	TestUUIDValue = "uuid"
 )
 
 // TestBed manages the setup and teardown phases of individual test cases.
@@ -42,12 +42,17 @@
 
 	// Force Service to re-use a fake UUID for testing by embedding the UUID in the
 	// context object.
-	ctx, err := SetTestUUID(context.Background(), TestUUID)
+	ctx, err := SetTestUUID(context.Background(), TestUUIDValue)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	return New(bed.MockRPCClient, authToken), ctx
+	ctx, err = SetAuthToken(ctx, authToken)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	return New(bed.MockRPCClient), ctx
 }
 
 // Teardown is used to clean up after every test-case.
@@ -88,8 +93,8 @@
 		testBed.ExpectRPC().
 			CreateInvocation(ctx, &api.CreateInvocationRequest{
 				AuthorizationToken: "auth_token",
-				RequestId:          TestUUID,
-				InvocationId:       TestUUID,
+				RequestId:          TestUUIDValue,
+				InvocationId:       TestUUIDValue,
 				Invocation:         input.ToResultStoreInvocation(),
 			}).
 			Return(input.ToResultStoreInvocation(), nil)
@@ -172,7 +177,7 @@
 
 		testBed.ExpectRPC().
 			CreateConfiguration(ctx, &api.CreateConfigurationRequest{
-				RequestId:          TestUUID,
+				RequestId:          TestUUIDValue,
 				AuthorizationToken: "auth_token",
 				Parent:             "invocation_name",
 				ConfigId:           "configuration_id",
@@ -204,7 +209,7 @@
 
 		testBed.ExpectRPC().
 			CreateTarget(ctx, &api.CreateTargetRequest{
-				RequestId:          TestUUID,
+				RequestId:          TestUUIDValue,
 				AuthorizationToken: "auth_token",
 				Parent:             "invocation_name",
 				TargetId:           input.ID,
@@ -291,7 +296,7 @@
 		testBed.ExpectRPC().
 			CreateConfiguredTarget(ctx, &api.CreateConfiguredTargetRequest{
 				AuthorizationToken: "auth_token",
-				RequestId:          TestUUID,
+				RequestId:          TestUUIDValue,
 				Parent:             "target_name",
 				ConfigId:           "configuration_id",
 				ConfiguredTarget:   input.ToResultStoreConfiguredTarget(),
@@ -377,7 +382,7 @@
 
 		testBed.ExpectRPC().
 			CreateAction(ctx, &api.CreateActionRequest{
-				RequestId:          TestUUID,
+				RequestId:          TestUUIDValue,
 				AuthorizationToken: "auth_token",
 				Parent:             "configured_target_name",
 				ActionId:           input.ID,