github.com/cs3org/reva/v2@v2.27.7/pkg/siteacc/manager/token.go (about) 1 // Copyright 2018-2020 CERN 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 // 15 // In applying this license, CERN does not waive the privileges and immunities 16 // granted to it by virtue of its status as an Intergovernmental Organization 17 // or submit itself to any jurisdiction. 18 19 package manager 20 21 import ( 22 "time" 23 24 "github.com/golang-jwt/jwt/v5" 25 "github.com/pkg/errors" 26 "github.com/sethvargo/go-password/password" 27 ) 28 29 type userToken struct { 30 jwt.RegisteredClaims 31 32 User string `json:"user"` 33 Scope string `json:"scope"` 34 } 35 36 const ( 37 tokenKeyLength = 16 38 tokenIssuer = "sciencemesh_siteacc" 39 ) 40 41 var ( 42 tokenSecret string 43 ) 44 45 func generateUserToken(user string, scope string, timeout int) (string, error) { 46 // Create a JWT as the user token 47 claims := userToken{ 48 RegisteredClaims: jwt.RegisteredClaims{ 49 ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(timeout) * time.Second)), 50 Issuer: tokenIssuer, 51 IssuedAt: jwt.NewNumericDate(time.Now()), 52 }, 53 User: user, 54 Scope: scope, 55 } 56 57 token := jwt.NewWithClaims(jwt.GetSigningMethod("HS256"), claims) 58 signedToken, err := token.SignedString([]byte(tokenSecret)) 59 if err != nil { 60 return "", errors.Wrapf(err, "error signing token with claims %+v", claims) 61 } 62 63 return signedToken, nil 64 } 65 66 func extractUserToken(token string) (*userToken, error) { 67 // Parse the token and try to extract the claims 68 parsedToken, err := jwt.ParseWithClaims(token, &userToken{}, func(token *jwt.Token) (interface{}, error) { return []byte(tokenSecret), nil }) 69 if err != nil { 70 return nil, errors.Wrap(err, "error parsing token") 71 } 72 73 if claims, ok := parsedToken.Claims.(*userToken); ok && parsedToken.Valid { 74 if claims.Issuer != tokenIssuer { 75 return nil, errors.Errorf("invalid token issuer") 76 } 77 78 return claims, nil 79 } 80 81 return nil, errors.Errorf("invalid token") 82 } 83 84 func init() { 85 // Generate the token secret randomly 86 tokenSecret = password.MustGenerate(tokenKeyLength, tokenKeyLength/4, tokenKeyLength/4, false, true) 87 }