diff --git a/object/user_upload.go b/object/user_upload.go index c4df3d6e..fcbcb074 100644 --- a/object/user_upload.go +++ b/object/user_upload.go @@ -81,62 +81,12 @@ func UploadUsers(owner string, path string) (bool, error) { return false, err } + transUsers, err := StringArrayToUser(table) + if err != nil { + return false, err + } newUsers := []*User{} - for index, line := range table { - line := line - if index == 0 || parseLineItem(&line, 0) == "" { - continue - } - - user := &User{ - Owner: parseLineItem(&line, 0), - Name: parseLineItem(&line, 1), - CreatedTime: parseLineItem(&line, 2), - UpdatedTime: parseLineItem(&line, 3), - Id: parseLineItem(&line, 4), - Type: parseLineItem(&line, 5), - Password: parseLineItem(&line, 6), - PasswordSalt: parseLineItem(&line, 7), - DisplayName: parseLineItem(&line, 8), - FirstName: parseLineItem(&line, 9), - LastName: parseLineItem(&line, 10), - Avatar: parseLineItem(&line, 11), - PermanentAvatar: "", - Email: parseLineItem(&line, 12), - Phone: parseLineItem(&line, 13), - Location: parseLineItem(&line, 14), - Address: []string{parseLineItem(&line, 15)}, - Affiliation: parseLineItem(&line, 16), - Title: parseLineItem(&line, 17), - IdCardType: parseLineItem(&line, 18), - IdCard: parseLineItem(&line, 19), - Homepage: parseLineItem(&line, 20), - Bio: parseLineItem(&line, 21), - Tag: parseLineItem(&line, 22), - Region: parseLineItem(&line, 23), - Language: parseLineItem(&line, 24), - Gender: parseLineItem(&line, 25), - Birthday: parseLineItem(&line, 26), - Education: parseLineItem(&line, 27), - Score: parseLineItemInt(&line, 28), - Karma: parseLineItemInt(&line, 29), - Ranking: parseLineItemInt(&line, 30), - IsDefaultAvatar: false, - IsOnline: parseLineItemBool(&line, 31), - IsAdmin: parseLineItemBool(&line, 32), - IsForbidden: parseLineItemBool(&line, 33), - IsDeleted: parseLineItemBool(&line, 34), - SignupApplication: parseLineItem(&line, 35), - Hash: "", - PreHash: "", - CreatedIp: parseLineItem(&line, 36), - LastSigninTime: parseLineItem(&line, 37), - LastSigninIp: parseLineItem(&line, 38), - Ldap: "", - Properties: map[string]string{}, - DeletedTime: parseLineItem(&line, 39), - } - + for _, user := range transUsers { if _, ok := oldUserMap[user.GetId()]; !ok { newUsers = append(newUsers, user) } diff --git a/object/user_util.go b/object/user_util.go index f55f9715..938f1727 100644 --- a/object/user_util.go +++ b/object/user_util.go @@ -19,12 +19,14 @@ import ( "fmt" "reflect" "regexp" + "strconv" "strings" "github.com/casdoor/casdoor/conf" "github.com/casdoor/casdoor/i18n" "github.com/casdoor/casdoor/idp" "github.com/casdoor/casdoor/util" + "github.com/go-webauthn/webauthn/webauthn" jsoniter "github.com/json-iterator/go" "github.com/xorm-io/core" ) @@ -689,3 +691,103 @@ func IsAppUser(userId string) bool { } return false } + +func setReflectAttr[T any](fieldValue *reflect.Value, fieldString string) error { + unmarshalValue := new(T) + err := json.Unmarshal([]byte(fieldString), unmarshalValue) + if err != nil { + return err + } + + fvElem := fieldValue + fvElem.Set(reflect.ValueOf(*unmarshalValue)) + return nil +} + +func StringArrayToUser(stringArray [][]string) ([]*User, error) { + fieldNames := stringArray[0] + excelMap := []map[string]string{} + userFieldMap := map[string]int{} + + reflectedUser := reflect.TypeOf(User{}) + for i := 0; i < reflectedUser.NumField(); i++ { + userFieldMap[strings.ToLower(reflectedUser.Field(i).Name)] = i + } + + for idx, field := range stringArray { + if idx == 0 { + continue + } + + tempMap := map[string]string{} + for idx, val := range field { + tempMap[fieldNames[idx]] = val + } + excelMap = append(excelMap, tempMap) + } + + users := []*User{} + var err error + + for _, u := range excelMap { + user := User{} + reflectedUser := reflect.ValueOf(&user).Elem() + for k, v := range u { + if v == "" || v == "null" || v == "[]" || v == "{}" { + continue + } + fName := strings.ToLower(strings.ReplaceAll(k, "_", "")) + fieldIdx, ok := userFieldMap[fName] + if !ok { + continue + } + fv := reflectedUser.Field(fieldIdx) + if !fv.IsValid() { + continue + } + switch fv.Kind() { + case reflect.String: + fv.SetString(v) + continue + case reflect.Bool: + fv.SetBool(v == "1") + continue + case reflect.Int: + intVal, err := strconv.Atoi(v) + if err != nil { + return nil, err + } + fv.SetInt(int64(intVal)) + continue + } + + switch fv.Type() { + case reflect.TypeOf([]string{}): + err = setReflectAttr[[]string](&fv, v) + case reflect.TypeOf([]*string{}): + err = setReflectAttr[[]*string](&fv, v) + case reflect.TypeOf([]*FaceId{}): + err = setReflectAttr[[]*FaceId](&fv, v) + case reflect.TypeOf([]*MfaProps{}): + err = setReflectAttr[[]*MfaProps](&fv, v) + case reflect.TypeOf([]*Role{}): + err = setReflectAttr[[]*Role](&fv, v) + case reflect.TypeOf([]*Permission{}): + err = setReflectAttr[[]*Permission](&fv, v) + case reflect.TypeOf([]ManagedAccount{}): + err = setReflectAttr[[]ManagedAccount](&fv, v) + case reflect.TypeOf([]MfaAccount{}): + err = setReflectAttr[[]MfaAccount](&fv, v) + case reflect.TypeOf([]webauthn.Credential{}): + err = setReflectAttr[[]webauthn.Credential](&fv, v) + } + + if err != nil { + return nil, err + } + } + users = append(users, &user) + } + + return users, nil +} diff --git a/xlsx/user_test.xlsx b/xlsx/user_test.xlsx index 95d42962..da2f435a 100644 Binary files a/xlsx/user_test.xlsx and b/xlsx/user_test.xlsx differ