Ejemplo n.º 1
0
func (s *SignupEngine) join(a libkb.LoginContext, username, email, inviteCode string, skipMail bool) error {
	joinEngine := NewSignupJoinEngine(s.G())

	arg := SignupJoinEngineRunArg{
		Username:   username,
		Email:      email,
		InviteCode: inviteCode,
		PWHash:     s.ppStream.PWHash(),
		PWSalt:     s.pwsalt,
		SkipMail:   skipMail,
	}
	res := joinEngine.Run(a, arg)
	if res.Err != nil {
		return res
	}

	s.ppStream.SetGeneration(res.PpGen)
	a.CreateStreamCache(s.tsec, s.ppStream)

	s.uid = res.UID
	s.G().Log.Debug("contextified: %v\n", s.G())
	user, err := libkb.LoadUser(libkb.LoadUserArg{Self: true, UID: res.UID, PublicKeyOptional: true, Contextified: libkb.NewContextified(s.G())})
	if err != nil {
		return err
	}
	s.me = user
	return nil
}
Ejemplo n.º 2
0
func (s *SignupJoinEngine) WriteOut(lctx libkb.LoginContext, salt []byte) error {
	if err := lctx.LocalSession().Load(); err != nil {
		return err
	}
	if err := lctx.CreateLoginSessionWithSalt(s.username.String(), salt); err != nil {
		return err
	}
	if err := lctx.SaveState(s.session, s.csrf, s.username, s.uid); err != nil {
		return err
	}
	return nil
}
Ejemplo n.º 3
0
func (e *LoginEngine) postLogin(ctx *Context, lctx libkb.LoginContext) error {
	// We might need to ID ourselves, so load us in here
	var err error
	arg := libkb.NewLoadUserForceArg(e.G())
	arg.LoginContext = lctx
	e.user, err = libkb.LoadMe(arg)
	if err != nil {
		_, ok := err.(libkb.NoKeyError)
		if !ok {
			return err
		}
	}

	if e.SkipLocksmith {
		ctx.LogUI.Debug("skipping locksmith as requested by LoginArg")
		return nil
	}

	// create a locksmith engine to check the account

	ctx.LoginContext = lctx
	larg := &LocksmithArg{
		User:      e.user,
		CheckOnly: true,
	}
	e.locksmith = NewLocksmith(larg, e.G())
	if err := RunEngine(e.locksmith, ctx); err != nil {
		return err
	}
	if e.locksmith.Status().CurrentDeviceOk {
		if err := lctx.LocalSession().SetDeviceProvisioned(e.G().Env.GetDeviceID()); err != nil {
			// not a fatal error, session will stay in memory
			e.G().Log.Warning("error saving session file: %s", err)
		}
		return nil
	}

	// need to provision this device

	// need to have passphrase stream cached in order to provision a device
	if lctx.PassphraseStreamCache() == nil {
		// this can happen if:
		// 1. The user is logging in for the first time on a device.
		// 2. Before the device is provisioned, the login is canceled or
		//    interrupted.
		// 3. The daemon restarts (`ctl stop`, machine reboot, bug, etc.)
		// 4. The login session is still valid, so the next login attempt
		//    does not require passphrase.
		//
		// (Note that pubkey login isn't an option until the device is
		// provisioned.)
		//
		// 5. So they get to here without entering their passphrase
		//    and without a cached passphrase stream.
		//    Locksmith won't be able to provision the device without
		//    the passphrase stream, and we can't do
		//    LoginState.verifyPassphraseWithServer since that creates
		//    a new login request and we are in the middle of a login
		//    request.
		//
		// The best we can do here is to logout and tell the user to
		// login again.  This should be a rare scenario.
		//
		lctx.Logout()
		ctx.LogUI.Info("Please run `keybase login` again.  There was an unexpected error since your previous login.")
		return libkb.ReloginRequiredError{}
	}

	larg.CheckOnly = false
	e.locksmith = NewLocksmith(larg, e.G())
	if err := RunEngine(e.locksmith, ctx); err != nil {
		if _, canceled := err.(libkb.CanceledError); canceled {
			lctx.Logout()
		}
		return err
	}

	if err := lctx.LocalSession().SetDeviceProvisioned(e.G().Env.GetDeviceID()); err != nil {
		// not a fatal error, session will stay in memory
		e.G().Log.Warning("error saving session file: %s", err)
	}
	return nil
}