go.temporal.io/server/tests/tls_test.go

99 LOC · 0 covered · 99 uncovered · 0 ranges · 0 concepts · 0 introducers · 0 tests

1 package tests
2
3 import (
4 "context"
5 "net/http"
6 "sync"
7 "testing"
8
9 "go.temporal.io/api/workflowservice/v1"
10 "go.temporal.io/server/common/authorization"
11 "go.temporal.io/server/common/testing/parallelsuite"
12 "go.temporal.io/server/tests/testcore"
13 )
14
15 type TLSFunctionalSuite struct {
16 parallelsuite.Suite[*TLSFunctionalSuite]
17 }
18
19 func TestTLSFunctionalSuite(t *testing.T) {
20 parallelsuite.Run(t, &TLSFunctionalSuite{})
21 }
22
23 func (s *TLSFunctionalSuite) newTestEnv(opts ...testcore.TestOption) *testcore.TestEnv {
24 baseOpts := []testcore.TestOption{
25 testcore.WithMTLS(),
26 }
27 return testcore.NewEnv(s.T(), append(baseOpts, opts...)...)
28 }
29
30 func (s *TLSFunctionalSuite) TestGRPCMTLS() {
31 env := s.newTestEnv()
32
33 // Track auth info
34 calls := s.trackAuthInfoByCall(env)
35
36 // Make a list-open call
37 _, _ = env.SdkClient().ListOpenWorkflow(s.Context(), &workflowservice.ListOpenWorkflowExecutionsRequest{})
38
39 // Confirm auth info as expected
40 authInfo, ok := calls.Load("/temporal.api.workflowservice.v1.WorkflowService/ListOpenWorkflowExecutions")
41 s.True(ok)
42 s.Equal(testcore.TlsCertCommonName, authInfo.(*authorization.AuthInfo).TLSSubject.CommonName)
43 }
44
45 func (s *TLSFunctionalSuite) TestHTTPMTLS() {
46 env := s.newTestEnv()
47 if env.HttpAPIAddress() == "" {
48 s.T().Skip("HTTP API server not enabled")
49 }
50 // Track auth info
51 calls := s.trackAuthInfoByCall(env)
52
53 // Confirm non-HTTPS call is rejected with 400
54 resp, err := http.Get("http://" + env.HttpAPIAddress() + "/namespaces/" + env.Namespace().String() + "/workflows")
55 s.NoError(err)
56 s.Equal(http.StatusBadRequest, resp.StatusCode)
57
58 // Create HTTP client with TLS config
59 httpClient := http.Client{
60 Transport: &http.Transport{
61 TLSClientConfig: env.GetTestCluster().Host().TLSConfigProvider().FrontendClientConfig,
62 },
63 }
64
65 // Make a list call
66 req, err := http.NewRequest("GET", "https://"+env.HttpAPIAddress()+"/namespaces/"+env.Namespace().String()+"/workflows", nil)
67 s.NoError(err)
68 resp, err = httpClient.Do(req)
69 s.NoError(err)
70 s.Equal(http.StatusOK, resp.StatusCode)
71
72 // Confirm auth info as expected
73 authInfo, ok := calls.Load("/temporal.api.workflowservice.v1.WorkflowService/ListWorkflowExecutions")
74 s.True(ok)
75 s.Equal(testcore.TlsCertCommonName, authInfo.(*authorization.AuthInfo).TLSSubject.CommonName)
76 }
77
78 func (s *TLSFunctionalSuite) trackAuthInfoByCall(env *testcore.TestEnv) *sync.Map {
79 var calls sync.Map
80 // Put auth info on claim, then use authorizer to set on the map by call
81 env.SetOnGetClaims(func(authInfo *authorization.AuthInfo) (*authorization.Claims, error) {
82 return &authorization.Claims{
83 System: authorization.RoleAdmin,
84 Extensions: authInfo,
85 }, nil
86 })
87 env.SetOnAuthorize(func(
88 ctx context.Context,
89 caller *authorization.Claims,
90 target *authorization.CallTarget,
91 ) (authorization.Result, error) {
92 //nolint:revive
93 if authInfo, _ := caller.Extensions.(*authorization.AuthInfo); authInfo != nil {
94 calls.Store(target.APIName, authInfo)
95 }
96 return authorization.Result{Decision: authorization.DecisionAllow}, nil
97 })
98 return &calls
99 }