github.com/cs3org/reva/v2@v2.27.7/pkg/auth/manager/serviceaccounts/serviceaccounts.go (about)

     1  package serviceaccounts
     2  
     3  import (
     4  	"context"
     5  
     6  	authpb "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
     7  	userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
     8  
     9  	"github.com/cs3org/reva/v2/pkg/auth"
    10  	"github.com/cs3org/reva/v2/pkg/auth/manager/registry"
    11  	"github.com/cs3org/reva/v2/pkg/auth/scope"
    12  	"github.com/mitchellh/mapstructure"
    13  	"github.com/pkg/errors"
    14  )
    15  
    16  type conf struct {
    17  	ServiceUsers []serviceuser `mapstructure:"service_accounts"`
    18  }
    19  
    20  type serviceuser struct {
    21  	ID     string `mapstructure:"id"`
    22  	Secret string `mapstructure:"secret"`
    23  }
    24  
    25  type manager struct {
    26  	authenticate func(userID, secret string) error
    27  }
    28  
    29  func init() {
    30  	registry.Register("serviceaccounts", New)
    31  }
    32  
    33  // Configure parses the map conf
    34  func (m *manager) Configure(config map[string]interface{}) error {
    35  	c := &conf{}
    36  	if err := mapstructure.Decode(config, c); err != nil {
    37  		return errors.Wrap(err, "error decoding conf")
    38  	}
    39  	// only inmem authenticator for now
    40  	a := &inmemAuthenticator{make(map[string]string)}
    41  	for _, s := range c.ServiceUsers {
    42  		a.m[s.ID] = s.Secret
    43  	}
    44  	m.authenticate = a.Authenticate
    45  	return nil
    46  }
    47  
    48  // New creates a new manager for the 'service' authentication
    49  func New(conf map[string]interface{}) (auth.Manager, error) {
    50  	m := &manager{}
    51  	err := m.Configure(conf)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  
    56  	return m, nil
    57  }
    58  
    59  // Authenticate authenticates the service account
    60  func (m *manager) Authenticate(ctx context.Context, userID string, secret string) (*userpb.User, map[string]*authpb.Scope, error) {
    61  	if err := m.authenticate(userID, secret); err != nil {
    62  		return nil, nil, err
    63  	}
    64  	scope, err := scope.AddOwnerScope(nil)
    65  	if err != nil {
    66  		return nil, nil, err
    67  	}
    68  	return &userpb.User{
    69  		// TODO: more details for service users?
    70  		Id: &userpb.UserId{
    71  			OpaqueId: userID,
    72  			Type:     userpb.UserType_USER_TYPE_SERVICE,
    73  			Idp:      "none",
    74  		},
    75  	}, scope, nil
    76  }
    77  
    78  type inmemAuthenticator struct {
    79  	m map[string]string
    80  }
    81  
    82  func (a *inmemAuthenticator) Authenticate(userID string, secret string) error {
    83  	if secret == "" || a.m[userID] == "" {
    84  		return errors.New("unknown user")
    85  	}
    86  	if a.m[userID] == secret {
    87  		return nil
    88  	}
    89  	return errors.New("secrets do not match")
    90  }