diff --git a/controllers/syncer.go b/controllers/syncer.go index baa03753..3dfeaf64 100644 --- a/controllers/syncer.go +++ b/controllers/syncer.go @@ -160,7 +160,11 @@ func (c *ApiController) RunSyncer() { return } - object.RunSyncer(syncer) + err = object.RunSyncer(syncer) + if err != nil { + c.ResponseError(err.Error()) + return + } c.ResponseOk() } diff --git a/object/syncer.go b/object/syncer.go index 23000d22..aeca983b 100644 --- a/object/syncer.go +++ b/object/syncer.go @@ -250,7 +250,7 @@ func (syncer *Syncer) getKey() string { return key } -func RunSyncer(syncer *Syncer) { +func RunSyncer(syncer *Syncer) error { syncer.initAdapter() - syncer.syncUsers() + return syncer.syncUsers() } diff --git a/object/syncer_cron.go b/object/syncer_cron.go index dc67dcc6..e2493017 100644 --- a/object/syncer_cron.go +++ b/object/syncer_cron.go @@ -52,11 +52,14 @@ func addSyncerJob(syncer *Syncer) error { syncer.initAdapter() - syncer.syncUsers() + err := syncer.syncUsers() + if err != nil { + return err + } schedule := fmt.Sprintf("@every %ds", syncer.SyncInterval) cron := getCronMap(syncer.Name) - _, err := cron.AddFunc(schedule, syncer.syncUsers) + _, err = cron.AddFunc(schedule, syncer.syncUsersNoError) if err != nil { return err } diff --git a/object/syncer_sync.go b/object/syncer_sync.go index 035935ff..5e219318 100644 --- a/object/syncer_sync.go +++ b/object/syncer_sync.go @@ -19,9 +19,9 @@ import ( "time" ) -func (syncer *Syncer) syncUsers() { +func (syncer *Syncer) syncUsers() error { if len(syncer.TableColumns) == 0 { - return + return fmt.Errorf("The syncer table columns should not be empty") } fmt.Printf("Running syncUsers()..\n") @@ -35,10 +35,8 @@ func (syncer *Syncer) syncUsers() { line := fmt.Sprintf("[%s] %s\n", timestamp, err.Error()) _, err = updateSyncerErrorText(syncer, line) if err != nil { - panic(err) + return err } - - return } fmt.Printf("Users: %d, oUsers: %d\n", len(users), len(oUsers)) @@ -71,28 +69,30 @@ func (syncer *Syncer) syncUsers() { updatedUser := syncer.createUserFromOriginalUser(oUser, affiliationMap) updatedUser.Hash = oHash updatedUser.PreHash = oHash + + fmt.Printf("Update from oUser to user: %v\n", updatedUser) _, err = syncer.updateUserForOriginalByFields(updatedUser, key) if err != nil { - panic(err) + return err } - fmt.Printf("Update from oUser to user: %v\n", updatedUser) } } else { if user.PreHash == oHash { if !syncer.IsReadOnly { updatedOUser := syncer.createOriginalUserFromUser(user) + + fmt.Printf("Update from user to oUser: %v\n", updatedOUser) _, err = syncer.updateUser(updatedOUser) if err != nil { - panic(err) + return err } - fmt.Printf("Update from user to oUser: %v\n", updatedOUser) } // update preHash user.PreHash = user.Hash _, err = SetUserField(user, "pre_hash", user.PreHash) if err != nil { - panic(err) + return err } } else { if user.Hash == oHash { @@ -100,17 +100,18 @@ func (syncer *Syncer) syncUsers() { user.PreHash = user.Hash _, err = SetUserField(user, "pre_hash", user.PreHash) if err != nil { - panic(err) + return err } } else { updatedUser := syncer.createUserFromOriginalUser(oUser, affiliationMap) updatedUser.Hash = oHash updatedUser.PreHash = oHash + + fmt.Printf("Update from oUser to user (2nd condition): %v\n", updatedUser) _, err = syncer.updateUserForOriginalByFields(updatedUser, key) if err != nil { - panic(err) + return err } - fmt.Printf("Update from oUser to user (2nd condition): %v\n", updatedUser) } } } @@ -118,7 +119,7 @@ func (syncer *Syncer) syncUsers() { } _, err = AddUsersInBatch(newUsers) if err != nil { - panic(err) + return err } if !syncer.IsReadOnly { @@ -126,12 +127,22 @@ func (syncer *Syncer) syncUsers() { id := user.Id if _, ok := oUserMap[id]; !ok { newOUser := syncer.createOriginalUserFromUser(user) + + fmt.Printf("New oUser: %v\n", newOUser) _, err = syncer.addUser(newOUser) if err != nil { - panic(err) + return err } - fmt.Printf("New oUser: %v\n", newOUser) } } } + + return nil +} + +func (syncer *Syncer) syncUsersNoError() { + err := syncer.syncUsers() + if err != nil { + panic(err) + } } diff --git a/web/src/SyncerEditPage.js b/web/src/SyncerEditPage.js index 0c4670b3..9bb40c86 100644 --- a/web/src/SyncerEditPage.js +++ b/web/src/SyncerEditPage.js @@ -234,12 +234,30 @@ class SyncerEditPage extends React.Component { + + + {Setting.getLabel(i18next.t("syncer:Database type"), i18next.t("syncer:Database type - Tooltip"))} : + + + + + {Setting.getLabel(i18next.t("provider:Host"), i18next.t("provider:Host - Tooltip"))} : - { + } value={this.state.syncer.host} onChange={e => { this.updateSyncerField("host", e.target.value); }} /> @@ -274,24 +292,6 @@ class SyncerEditPage extends React.Component { }} /> - - - {Setting.getLabel(i18next.t("syncer:Database type"), i18next.t("syncer:Database type - Tooltip"))} : - - - - - {Setting.getLabel(i18next.t("syncer:Database"), i18next.t("syncer:Database - Tooltip"))} : diff --git a/web/src/SyncerListPage.js b/web/src/SyncerListPage.js index 79c02647..f2b03dd9 100644 --- a/web/src/SyncerListPage.js +++ b/web/src/SyncerListPage.js @@ -86,8 +86,13 @@ class SyncerListPage extends BaseListPage { this.setState({loading: true}); SyncerBackend.runSyncer("admin", this.state.data[i].name) .then((res) => { - this.setState({loading: false}); - Setting.showMessage("success", "Syncer sync users successfully"); + if (res.status === "ok") { + this.setState({loading: false}); + Setting.showMessage("success", i18next.t("general:Successfully synced")); + } else { + this.setState({loading: false}); + Setting.showMessage("error", `${i18next.t("general:Failed to sync")}: ${res.msg}`); + } } ) .catch(error => { @@ -151,6 +156,13 @@ class SyncerListPage extends BaseListPage { {text: "LDAP", value: "LDAP"}, ], }, + { + title: i18next.t("syncer:Database type"), + dataIndex: "databaseType", + key: "databaseType", + width: "130px", + sorter: (a, b) => a.databaseType.localeCompare(b.databaseType), + }, { title: i18next.t("provider:Host"), dataIndex: "host", @@ -183,13 +195,6 @@ class SyncerListPage extends BaseListPage { sorter: true, ...this.getColumnSearchProps("password"), }, - { - title: i18next.t("syncer:Database type"), - dataIndex: "databaseType", - key: "databaseType", - width: "120px", - sorter: (a, b) => a.databaseType.localeCompare(b.databaseType), - }, { title: i18next.t("syncer:Database"), dataIndex: "database", @@ -208,7 +213,7 @@ class SyncerListPage extends BaseListPage { title: i18next.t("syncer:Sync interval"), dataIndex: "syncInterval", key: "syncInterval", - width: "130px", + width: "140px", sorter: true, ...this.getColumnSearchProps("syncInterval"), }, diff --git a/web/src/table/SyncerTableColumnTable.js b/web/src/table/SyncerTableColumnTable.js index e4764520..b7bde74d 100644 --- a/web/src/table/SyncerTableColumnTable.js +++ b/web/src/table/SyncerTableColumnTable.js @@ -96,7 +96,7 @@ class SyncerTableColumnTable extends React.Component { key: "casdoorName", render: (text, record, index) => { return ( - {this.updateField(table, index, "casdoorName", value);})}> { ["Name", "CreatedTime", "UpdatedTime", "Id", "Type", "Password", "PasswordSalt", "DisplayName", "FirstName", "LastName", "Avatar", "PermanentAvatar", "Email", "EmailVerified", "Phone", "Location", "Address", "Affiliation", "Title", "IdCardType", "IdCard", "Homepage", "Bio", "Tag", "Region",