Initial QSfera import
This commit is contained in:
+95
@@ -0,0 +1,95 @@
|
||||
// Copyright 2018-2021 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package demo
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/gob"
|
||||
|
||||
auth "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
|
||||
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/token"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/token/manager/registry"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func init() {
|
||||
registry.Register("demo", New)
|
||||
}
|
||||
|
||||
// New returns a new token manager.
|
||||
func New(m map[string]interface{}) (token.Manager, error) {
|
||||
mngr := manager{}
|
||||
return &mngr, nil
|
||||
}
|
||||
|
||||
type manager struct{}
|
||||
|
||||
type claims struct {
|
||||
User *user.User `json:"user"`
|
||||
Scope map[string]*auth.Scope `json:"scope"`
|
||||
}
|
||||
|
||||
func (m *manager) MintToken(ctx context.Context, u *user.User, scope map[string]*auth.Scope) (string, error) {
|
||||
token, err := encode(&claims{u, scope})
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "error encoding user")
|
||||
}
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (m *manager) DismantleToken(ctx context.Context, token string) (*user.User, map[string]*auth.Scope, error) {
|
||||
c, err := decode(token)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "error decoding claims")
|
||||
}
|
||||
return c.User, c.Scope, nil
|
||||
}
|
||||
|
||||
// from https://stackoverflow.com/questions/28020070/golang-serialize-and-deserialize-back
|
||||
// go binary encoder
|
||||
func encode(c *claims) (string, error) {
|
||||
b := bytes.Buffer{}
|
||||
e := gob.NewEncoder(&b)
|
||||
err := e.Encode(c)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(b.Bytes()), nil
|
||||
}
|
||||
|
||||
// from https://stackoverflow.com/questions/28020070/golang-serialize-and-deserialize-back
|
||||
// go binary decoder
|
||||
func decode(token string) (*claims, error) {
|
||||
c := &claims{}
|
||||
by, err := base64.StdEncoding.DecodeString(token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
b := bytes.Buffer{}
|
||||
b.Write(by)
|
||||
d := gob.NewDecoder(&b)
|
||||
err = d.Decode(&c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
+132
@@ -0,0 +1,132 @@
|
||||
// Copyright 2018-2021 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package jwt
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
auth "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
|
||||
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/errtypes"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/sharedconf"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/token"
|
||||
"github.com/opencloud-eu/reva/v2/pkg/token/manager/registry"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const defaultExpiration int64 = 86400 // 1 day
|
||||
const defaultLeeway int64 = 5 // 5 seconds
|
||||
|
||||
func init() {
|
||||
registry.Register("jwt", New)
|
||||
}
|
||||
|
||||
type config struct {
|
||||
Secret string `mapstructure:"secret"`
|
||||
Expires int64 `mapstructure:"expires"`
|
||||
tokenTimeLeeway int64 `mapstructure:"token_leeway"`
|
||||
}
|
||||
|
||||
type manager struct {
|
||||
conf *config
|
||||
}
|
||||
|
||||
// claims are custom claims for the JWT token.
|
||||
type claims struct {
|
||||
jwt.RegisteredClaims
|
||||
User *user.User `json:"user"`
|
||||
Scope map[string]*auth.Scope `json:"scope"`
|
||||
}
|
||||
|
||||
func parseConfig(m map[string]interface{}) (*config, error) {
|
||||
c := &config{}
|
||||
if err := mapstructure.Decode(m, c); err != nil {
|
||||
err = errors.Wrap(err, "error decoding conf")
|
||||
return nil, err
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// New returns an implementation of the token manager that uses JWT as tokens.
|
||||
func New(value map[string]interface{}) (token.Manager, error) {
|
||||
c, err := parseConfig(value)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error parsing config")
|
||||
}
|
||||
|
||||
if c.Expires == 0 {
|
||||
c.Expires = defaultExpiration
|
||||
}
|
||||
|
||||
if c.tokenTimeLeeway == 0 {
|
||||
c.tokenTimeLeeway = defaultLeeway
|
||||
}
|
||||
|
||||
c.Secret = sharedconf.GetJWTSecret(c.Secret)
|
||||
|
||||
if c.Secret == "" {
|
||||
return nil, errors.New("jwt: secret for signing payloads is not defined in config")
|
||||
}
|
||||
|
||||
m := &manager{conf: c}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
func (m *manager) MintToken(ctx context.Context, u *user.User, scope map[string]*auth.Scope) (string, error) {
|
||||
ttl := time.Duration(m.conf.Expires) * time.Second
|
||||
newClaims := claims{
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(ttl)),
|
||||
Issuer: u.Id.Idp,
|
||||
Audience: jwt.ClaimStrings{"reva"},
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
},
|
||||
User: u,
|
||||
Scope: scope,
|
||||
}
|
||||
|
||||
t := jwt.NewWithClaims(jwt.GetSigningMethod("HS256"), newClaims)
|
||||
|
||||
tkn, err := t.SignedString([]byte(m.conf.Secret))
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "error signing token with claims %+v", newClaims)
|
||||
}
|
||||
|
||||
return tkn, nil
|
||||
}
|
||||
|
||||
func (m *manager) DismantleToken(ctx context.Context, tkn string) (*user.User, map[string]*auth.Scope, error) {
|
||||
keyfunc := func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte(m.conf.Secret), nil
|
||||
}
|
||||
token, err := jwt.ParseWithClaims(tkn, &claims{}, keyfunc, jwt.WithLeeway(time.Duration(m.conf.tokenTimeLeeway)*time.Second))
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrap(err, "error parsing token")
|
||||
}
|
||||
|
||||
if claims, ok := token.Claims.(*claims); ok && token.Valid {
|
||||
return claims.User, claims.Scope, nil
|
||||
}
|
||||
|
||||
return nil, nil, errtypes.InvalidCredentials("invalid token")
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// Copyright 2018-2021 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package loader
|
||||
|
||||
import (
|
||||
// Load core token managers.
|
||||
_ "github.com/opencloud-eu/reva/v2/pkg/token/manager/demo"
|
||||
_ "github.com/opencloud-eu/reva/v2/pkg/token/manager/jwt"
|
||||
// Add your own here.
|
||||
)
|
||||
Generated
Vendored
+34
@@ -0,0 +1,34 @@
|
||||
// Copyright 2018-2021 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package registry
|
||||
|
||||
import "github.com/opencloud-eu/reva/v2/pkg/token"
|
||||
|
||||
// NewFunc is the function that token managers
|
||||
// should register at init time.
|
||||
type NewFunc func(map[string]interface{}) (token.Manager, error)
|
||||
|
||||
// NewFuncs is a map containing all the registered token managers.
|
||||
var NewFuncs = map[string]NewFunc{}
|
||||
|
||||
// Register registers a new token manager new function.
|
||||
// Not safe for concurrent use. Safe for use from package init.
|
||||
func Register(name string, f NewFunc) {
|
||||
NewFuncs[name] = f
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
// Copyright 2018-2021 CERN
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// In applying this license, CERN does not waive the privileges and immunities
|
||||
// granted to it by virtue of its status as an Intergovernmental Organization
|
||||
// or submit itself to any jurisdiction.
|
||||
|
||||
package token
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
auth "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
|
||||
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
)
|
||||
|
||||
// Manager is the interface to implement to sign and verify tokens
|
||||
type Manager interface {
|
||||
MintToken(ctx context.Context, u *user.User, scope map[string]*auth.Scope) (string, error)
|
||||
DismantleToken(ctx context.Context, token string) (*user.User, map[string]*auth.Scope, error)
|
||||
}
|
||||
Reference in New Issue
Block a user