github.com/cs3org/reva/v2@v2.27.7/internal/grpc/services/authprovider/authprovider.go (about)

     1  // Copyright 2018-2021 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 authprovider
    20  
    21  import (
    22  	"context"
    23  	"fmt"
    24  	"path/filepath"
    25  
    26  	provider "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
    27  	"github.com/cs3org/reva/v2/pkg/appctx"
    28  	"github.com/cs3org/reva/v2/pkg/auth"
    29  	"github.com/cs3org/reva/v2/pkg/auth/manager/registry"
    30  	"github.com/cs3org/reva/v2/pkg/errtypes"
    31  	"github.com/cs3org/reva/v2/pkg/plugin"
    32  	"github.com/cs3org/reva/v2/pkg/rgrpc"
    33  	"github.com/cs3org/reva/v2/pkg/rgrpc/status"
    34  	"github.com/mitchellh/mapstructure"
    35  	"github.com/pkg/errors"
    36  	"github.com/rs/zerolog"
    37  	"google.golang.org/grpc"
    38  )
    39  
    40  func init() {
    41  	rgrpc.Register("authprovider", New)
    42  }
    43  
    44  type config struct {
    45  	AuthManager  string                            `mapstructure:"auth_manager"`
    46  	AuthManagers map[string]map[string]interface{} `mapstructure:"auth_managers"`
    47  }
    48  
    49  func (c *config) init() {
    50  	if c.AuthManager == "" {
    51  		c.AuthManager = "json"
    52  	}
    53  }
    54  
    55  type service struct {
    56  	authmgr auth.Manager
    57  	conf    *config
    58  	plugin  *plugin.RevaPlugin
    59  }
    60  
    61  func parseConfig(m map[string]interface{}) (*config, error) {
    62  	c := &config{}
    63  	if err := mapstructure.Decode(m, c); err != nil {
    64  		err = errors.Wrap(err, "error decoding conf")
    65  		return nil, err
    66  	}
    67  	c.init()
    68  	return c, nil
    69  }
    70  
    71  func getAuthManager(manager string, m map[string]map[string]interface{}) (auth.Manager, *plugin.RevaPlugin, error) {
    72  	if manager == "" {
    73  		return nil, nil, errtypes.InternalError("authsvc: driver not configured for auth manager")
    74  	}
    75  	p, err := plugin.Load("authprovider", manager)
    76  	if err == nil {
    77  		authManager, ok := p.Plugin.(auth.Manager)
    78  		if !ok {
    79  			return nil, nil, fmt.Errorf("could not assert the loaded plugin")
    80  		}
    81  		pluginConfig := filepath.Base(manager)
    82  		err = authManager.Configure(m[pluginConfig])
    83  		if err != nil {
    84  			return nil, nil, err
    85  		}
    86  		return authManager, p, nil
    87  	} else if _, ok := err.(errtypes.NotFound); ok {
    88  		if f, ok := registry.NewFuncs[manager]; ok {
    89  			authmgr, err := f(m[manager])
    90  			return authmgr, nil, err
    91  		}
    92  	} else {
    93  		return nil, nil, err
    94  	}
    95  	return nil, nil, errtypes.NotFound(fmt.Sprintf("authsvc: driver %s not found for auth manager", manager))
    96  }
    97  
    98  // New returns a new AuthProviderServiceServer.
    99  func New(m map[string]interface{}, ss *grpc.Server, _ *zerolog.Logger) (rgrpc.Service, error) {
   100  	c, err := parseConfig(m)
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  
   105  	authManager, plug, err := getAuthManager(c.AuthManager, c.AuthManagers)
   106  	if err != nil {
   107  		return nil, err
   108  	}
   109  
   110  	svc := &service{
   111  		conf:    c,
   112  		authmgr: authManager,
   113  		plugin:  plug,
   114  	}
   115  
   116  	return svc, nil
   117  }
   118  
   119  func (s *service) Close() error {
   120  	if s.plugin != nil {
   121  		s.plugin.Kill()
   122  	}
   123  	return nil
   124  }
   125  
   126  func (s *service) UnprotectedEndpoints() []string {
   127  	return []string{"/cs3.auth.provider.v1beta1.ProviderAPI/Authenticate"}
   128  }
   129  
   130  func (s *service) Register(ss *grpc.Server) {
   131  	provider.RegisterProviderAPIServer(ss, s)
   132  }
   133  
   134  func (s *service) Authenticate(ctx context.Context, req *provider.AuthenticateRequest) (*provider.AuthenticateResponse, error) {
   135  	log := appctx.GetLogger(ctx)
   136  	username := req.ClientId
   137  	password := req.ClientSecret
   138  
   139  	u, scope, err := s.authmgr.Authenticate(ctx, username, password)
   140  	if err != nil {
   141  		log.Debug().Str("client_id", username).Err(err).Msg("authsvc: error in Authenticate")
   142  		return &provider.AuthenticateResponse{
   143  			Status: status.NewStatusFromErrType(ctx, "authsvc: error in Authenticate", err),
   144  		}, nil
   145  	}
   146  	log.Info().Msgf("user %s authenticated", u.Id)
   147  	return &provider.AuthenticateResponse{
   148  		Status:     status.NewOK(ctx),
   149  		User:       u,
   150  		TokenScope: scope,
   151  	}, nil
   152  }