Merge branch '21905-no-rvm-salt'
[arvados.git] / sdk / go / auth / salt.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 package auth
6
7 import (
8         "crypto/hmac"
9         "crypto/sha1"
10         "errors"
11         "fmt"
12         "io"
13         "regexp"
14         "strings"
15 )
16
17 var (
18         reObsoleteToken  = regexp.MustCompile(`^[0-9a-z]{41,}$`)
19         ErrObsoleteToken = errors.New("obsolete token format")
20         ErrTokenFormat   = errors.New("badly formatted token")
21         ErrSalted        = errors.New("token already salted")
22 )
23
24 func SaltToken(token, remote string) (string, error) {
25         parts := strings.Split(token, "/")
26         if len(parts) < 3 || parts[0] != "v2" {
27                 if reObsoleteToken.MatchString(token) {
28                         return "", ErrObsoleteToken
29                 }
30                 return "", ErrTokenFormat
31         }
32         uuid := parts[1]
33         secret := parts[2]
34         if strings.HasPrefix(uuid, remote) {
35                 // target cluster issued this token -- send the real
36                 // token
37                 return token, nil
38         } else if len(secret) != 40 {
39                 // not already salted
40                 hmac := hmac.New(sha1.New, []byte(secret))
41                 io.WriteString(hmac, remote)
42                 secret = fmt.Sprintf("%x", hmac.Sum(nil))
43                 return "v2/" + uuid + "/" + secret, nil
44         } else {
45                 // already salted, and not issued by target cluster --
46                 // can't be used
47                 return "", ErrSalted
48         }
49 }