in lib/dam/token_flow.go [384:461]
func (s *Service) loggedIn(ctx context.Context, in loggedInHandlerIn) (_ *loggedInHandlerOut, _ string, ferr error) {
tx, err := s.store.Tx(true)
if err != nil {
return nil, "", status.Errorf(codes.Unavailable, err.Error())
}
defer func() {
err := tx.Finish()
if ferr == nil && err != nil {
ferr = status.Errorf(codes.Internal, err.Error())
}
}()
state := &pb.ResourceTokenRequestState{}
err = s.store.ReadTx(storage.ResourceTokenRequestStateDataType, storage.DefaultRealm, storage.DefaultUser, in.stateID, storage.LatestRev, state, tx)
if err != nil {
if storage.ErrNotFound(err) {
return nil, "", status.Errorf(codes.InvalidArgument, err.Error())
}
return nil, "", status.Errorf(codes.Unavailable, err.Error())
}
if len(in.errStr) > 0 || len(in.errDesc) > 0 {
return nil, state.LoginChallenge, errutil.WithErrorReason(in.errStr, status.Errorf(codes.Unauthenticated, in.errDesc))
}
if len(in.authCode) == 0 {
return nil, state.LoginChallenge, status.Errorf(codes.InvalidArgument, "no auth code")
}
sec, err := s.loadSecrets(tx)
if err != nil {
return nil, state.LoginChallenge, status.Errorf(codes.Unavailable, err.Error())
}
realm := state.Realm
cfg, err := s.loadConfig(tx, realm)
if err != nil {
return nil, state.LoginChallenge, status.Errorf(codes.Unavailable, err.Error())
}
broker, ok := cfg.TrustedIssuers[state.Broker]
if !ok {
return nil, state.LoginChallenge, status.Errorf(codes.InvalidArgument, "unknown identity broker %q", state.Broker)
}
clientSecret, ok := sec.GetBrokerSecrets()[broker.ClientId]
if !ok {
return nil, state.LoginChallenge, status.Errorf(codes.FailedPrecondition, "client secret of broker %q is not defined", s.defaultBroker)
}
conf := s.oauthConf(state.Broker, broker, clientSecret, []string{})
tok, err := conf.Exchange(ctx, in.authCode)
if err != nil {
return nil, state.LoginChallenge, status.Errorf(codes.Unauthenticated, "token exchange failed. %s", err)
}
id, err := s.upstreamTokenToPassportIdentity(ctx, cfg, tx, tok.AccessToken, broker.ClientId)
if err != nil {
return nil, state.LoginChallenge, status.Errorf(codes.Unauthenticated, err.Error())
}
var subject string
if subject, err = s.createOrUpdateAccount(ctx, in.r, id, state.Broker, state.Realm, tx); err != nil {
return nil, state.LoginChallenge, err
}
// Add the upstream id to identities, and change id subject to dam account subject.
id.Identities[id.Subject] = nil
id.Subject = subject
if state.Type == pb.ResourceTokenRequestState_DATASET {
out, err := s.loggedInForDatasetToken(ctx, id, state, cfg, in.stateID, realm, tx)
return out, state.LoginChallenge, err
}
out, err := s.loggedInForEndpointToken(id, state, in.stateID, tx)
return out, state.LoginChallenge, err
}