blob: 2b226fa74ebf57f1189020afe9fd2c52ffd331ce [file] [log] [blame]
sslobodrd046be82019-01-16 10:02:22 -05001// Copyright 2017 The etcd Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package grpcproxy
16
17import (
18 "context"
19
20 "google.golang.org/grpc"
21 "google.golang.org/grpc/metadata"
22)
23
24func getAuthTokenFromClient(ctx context.Context) string {
25 md, ok := metadata.FromIncomingContext(ctx)
26 if ok {
27 ts, ok := md["token"]
28 if ok {
29 return ts[0]
30 }
31 }
32 return ""
33}
34
35func withClientAuthToken(ctx context.Context, ctxWithToken context.Context) context.Context {
36 token := getAuthTokenFromClient(ctxWithToken)
37 if token != "" {
38 ctx = context.WithValue(ctx, "token", token)
39 }
40 return ctx
41}
42
43type proxyTokenCredential struct {
44 token string
45}
46
47func (cred *proxyTokenCredential) RequireTransportSecurity() bool {
48 return false
49}
50
51func (cred *proxyTokenCredential) GetRequestMetadata(ctx context.Context, s ...string) (map[string]string, error) {
52 return map[string]string{
53 "token": cred.token,
54 }, nil
55}
56
57func AuthUnaryClientInterceptor(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
58 token := getAuthTokenFromClient(ctx)
59 if token != "" {
60 tokenCred := &proxyTokenCredential{token}
61 opts = append(opts, grpc.PerRPCCredentials(tokenCred))
62 }
63 return invoker(ctx, method, req, reply, cc, opts...)
64}
65
66func AuthStreamClientInterceptor(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
67 tokenif := ctx.Value("token")
68 if tokenif != nil {
69 tokenCred := &proxyTokenCredential{tokenif.(string)}
70 opts = append(opts, grpc.PerRPCCredentials(tokenCred))
71 }
72 return streamer(ctx, desc, cc, method, opts...)
73}