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 }
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 }
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 }