func doLogin(w http.ResponseWriter, r *http.Request) (interface{}, *pc.RestError) { var ginfo map[string]interface{} dec := json.NewDecoder(r.Body) var authResp AuthResponse if err := dec.Decode(&authResp); err != nil { return nil, &pc.RestError{ Message: "Could not decode auth data", HttpStatus: http.StatusBadRequest, WrappedException: err, } } if err := checkAuthResponse(&authResp, &loginOAuth2Config); err != nil { return nil, err } token, err := getGoogleToken(&authResp, &loginOAuth2Config) if err != nil { return nil, err } if err := pc.GetGoogleInfoFromToken( token.AccessToken, loginOAuth2Config.Config, &ginfo, ); err != nil { return nil, err } gid := ginfo["user_id"] var user pc.User if err := userC.Find(bson.M{"gid": gid}).One(&user); err != nil { if err == mgo.ErrNotFound { return nil, &pc.RestError{ WrappedException: err, Message: "You don't have a perfect account", HttpStatus: http.StatusUnauthorized, } } else { return nil, &pc.RestError{ WrappedException: err, Message: "Unexpected error occurred. We're gonna fix it!", HttpStatus: http.StatusInternalServerError, } } } return user, nil }
func InstallUser(w http.ResponseWriter, r *http.Request) (interface{}, *pc.RestError) { var ginfo map[string]interface{} var session *sessions.Session if err := pc.GetSession(cookieJar, r, &session); err != nil { return nil, err } authResp, ok := session.Values["INSTALL_AUTH_RESPONSE"].(*AuthResponse) if !ok { return nil, &pc.RestError{ Message: "Bad session, no auth response", HttpStatus: http.StatusBadRequest, } } session.Values["INSTALL_AUTH_RESPONSE"] = nil if err := checkAuthResponse(authResp, &installOAuth2Config); err != nil { return nil, err } gToken, err := getGoogleToken(authResp, &installOAuth2Config) if err != nil { return nil, err } if err := pc.GetGoogleInfoFromToken(gToken.AccessToken, installOAuth2Config.Config, &ginfo); err != nil { return nil, err } if authResp.UserToken == "" { return nil, &pc.RestError{ Message: "No userToken supplied", HttpStatus: http.StatusBadRequest, } } gid := fmt.Sprintf("%v", ginfo["user_id"]) email := fmt.Sprintf("%v", ginfo["email"]) tryUpsert := func(username string, retryCount int, user *pc.User) error { if retryCount > 0 { username = fmt.Sprintf("%s%d", username, retryCount) } update := mgo.Change{ Upsert: true, ReturnNew: true, Update: bson.M{ "$setOnInsert": bson.M{ "creationts": time.Now(), "gid": gid, "uuid": uuid.NewV4().String(), "authtoken": base64.StdEncoding.EncodeToString(uuid.NewV4().Bytes()), "refreshtoken": base64.StdEncoding.EncodeToString(uuid.NewV4().Bytes()), }, "$set": bson.M{ "email": email, "username": username, "ginfo": ginfo, "gtoken": gToken, }, }, } if _, err := userC.Find(bson.M{"gid": gid}).Apply(update, user); err != nil { return err } return nil } username := strings.ToLower(strings.Split(email, "@")[0]) username = sanitizeUsernameRegex.ReplaceAllLiteralString(username, "") for retryCount := 0; retryCount < 1000; retryCount++ { var user pc.User if err := tryUpsert(username, retryCount, &user); err != nil { if mgo.IsDup(err) && strings.Contains(err.Error(), "username") { continue } return nil, &pc.RestError{ WrappedException: err, Message: "Error creating user account", HttpStatus: http.StatusInternalServerError, } } //Use "user" object if _, err := pc.CreateMirrorAccount( user, authResp.UserToken, *baseJwtConfig, ); err != nil { return nil, &pc.RestError{ WrappedException: err, Message: "Error creating mirror account", HttpStatus: http.StatusInternalServerError, } } return user, nil } return nil, &pc.RestError{ Message: "Error creating user account", HttpStatus: http.StatusInternalServerError, } }