// Sync doorbot users with a foreign data source using a bridge. func Sync(render render.Render, r doorbot.Repositories, b bridges.Bridges, a *doorbot.Account, session *auth.Authorization) { var bUsers []*doorbot.BridgeUser var registered []*doorbot.BridgeUser var err error personRepo := r.PersonRepository() bUserRepo := r.BridgeUserRepository() var bridgesToSync = []uint{bridges.BridgeHub, bridges.BridgeHipChat} for _, bridgeId := range bridgesToSync { f := func() bool { users, err := b.GetUsers(bridgeId) for _, u := range users { log.WithFields(log.Fields{"user": *u}).Info("User") } if err != nil { log.WithFields(log.Fields{ "error": err, "account_id": a.ID, "bridge_id": bridgeId, }).Error("Api::People->Sync bridge error") return false } existing, err := bUserRepo.FindByBridgeID(r.DB(), bridgeId) if err != nil { log.WithFields(log.Fields{ "error": err, "account_id": r.AccountScope(), "step": "bridge-user-find-by-bridge-id", "bridge_id": bridgeId, }).Error("Api::People->Sync database error") return false } registered = append(registered, existing...) bUsers = append(bUsers, users...) return true } f() } tx, err := r.Transaction() if err != nil { log.WithFields(log.Fields{ "error": err, "account_id": r.AccountScope(), "step": "transaction-create", }).Error("Api::People->Sync database error") render.JSON(http.StatusInternalServerError, doorbot.NewInternalServerErrorResponse([]string{})) return } var buser *doorbot.BridgeUser for _, u := range bUsers { log.WithFields(log.Fields{ "account_id": r.AccountScope(), "bridge_user_id": u.UserID, "bridge_user_email": u.Email, "bridge_user_name": u.Name, }).Debug("Api::People->Sync bridge user") buser = findRegistered(registered, u.UserID) if buser != nil { log.WithFields(log.Fields{ "account_id": r.AccountScope(), "bridge_user_id": buser.UserID, "person_id": buser.PersonID, }).Debug("Api::People->Sync registered user found") person, err := personRepo.Find(tx, buser.PersonID) if err != nil { log.WithFields(log.Fields{ "error": err, "account_id": r.AccountScope(), "bridge_user_id": buser.UserID, "person_id": buser.PersonID, "step": "person-find-from-bridge-id", }).Error("Api::People->Sync database error") break } person.Name = u.Name person.Email = u.Email person.PhoneNumber = u.PhoneNumber _, err = personRepo.Update(tx, person) if err != nil { log.WithFields(log.Fields{ "error": err, "account_id": r.AccountScope(), "bridge_user_id": buser.UserID, "person_id": buser.PersonID, "step": "person-update-from-bridge-data", }).Error("Api::People->Sync database error") break } log.WithFields(log.Fields{ "account_id": r.AccountScope(), "bridge_user_id": buser.UserID, "person_id": buser.PersonID, }).Info("Api::People->Sync person updated from bridge data") continue } log.WithFields(log.Fields{ "account_id": r.AccountScope(), "bridge_user_id": u.UserID, "bridge_user_email": u.Email, "bridge_user_name": u.Name, }).Info("Api::People->Sync new bridge user") // User does not exists. Create them args := doorbot.PersonArguments{ Name: u.Name, Email: u.Email, } person := doorbot.NewPerson(args) err = personRepo.Create(tx, person) if err != nil { log.WithFields(log.Fields{ "error": err, "account_id": r.AccountScope(), "bridge_user_id": buser.UserID, "step": "person-create-from-bridge-data", }).Error("Api::People->Sync database error") break } u.PersonID = person.ID err = bUserRepo.Create(tx, u) if err != nil { log.WithFields(log.Fields{ "error": err, "account_id": r.AccountScope(), "bridge_user_id": buser.UserID, "step": "bridge-user-create", }).Error("Api::People->Sync database error") break } continue } if err != nil { log.WithFields(log.Fields{ "error": err, "account_id": r.AccountScope(), }).Error("Api::People->Sync error") tx.Rollback() render.JSON(http.StatusInternalServerError, doorbot.NewInternalServerErrorResponse([]string{})) return } err = tx.Commit() if err != nil { log.WithFields(log.Fields{ "error": err, "account_id": r.AccountScope(), "step": "transaction-commit", }).Error("Api::People->Sync database error") render.JSON(http.StatusInternalServerError, doorbot.NewInternalServerErrorResponse([]string{})) return } log.WithFields(log.Fields{ "account_id": r.AccountScope(), }).Info("Api::People->Sync bridge sync completed.") render.Status(http.StatusNoContent) }