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 }