package main import ( "crypto/hmac" "crypto/rand" "crypto/sha256" "fmt" "git.wecise.com/wecise/common/modb" "git.wecise.com/wecise/common/common" lp "git.wecise.com/wecise/common/ldap" "git.wecise.com/wecise/odb-go/odb" "hash" "sort" "strings" ) func main() { db, err := getDB() if err != nil { fmt.Printf(err.Error()) } // init data rands := getRandomString(10) salt := getRandomString(10) enAdminPasswd := PBKDF2([]byte("admin"), []byte(salt), 10000, 50, sha256.New) adminPasswd := fmt.Sprintf("%x", enAdminPasswd) users := []*lp.Object{ { Id: "/", Parent: "", UserName: "/", FullName: "/", Passwd: "", Otype: "org", Lft: 0, }, { Id: "/admin", Parent: "/", UserName: "admin", FullName: "/admin", Passwd: adminPasswd, Otype: "usr", Rands: rands, Salt: salt, IsAdmin: true, IsActive: true, }, } buildTree(users[0].Parent, users[0].Lft, users) // Truncate ldap and group if _, err = db.Query("delete from /matrix/ldap with version").Do(); err != nil { fmt.Printf(err.Error()) } if _, err = db.Query("delete from /matrix/group with version").Do(); err != nil { fmt.Printf(err.Error()) } for _, u := range users { if err = createObjectFromObject("/matrix/ldap", u, db); err != nil { fmt.Printf(err.Error()) } } // Create group res, err := db.Query("select id, username, fullname, parent from /matrix/ldap where otype = 'org' refresh").Do() if err != nil { fmt.Printf(err.Error()) } orgs := res.Data mql := `insert into /matrix/group (parent, name, fullname, isldap, member) values (?, ?, ?, ?, ?)` var adminMember []string for _, org := range orgs { usrsRes, err := db.Query("select fullname, isadmin from /matrix/ldap where parent = '" + org["fullname"].(string) + "' and otype = 'usr' refresh").Do() if err != nil { fmt.Printf(err.Error()) } usrs := usrsRes.Data var memeber []string for i := range usrs { umem := "U" + usrs[i]["fullname"].(string) memeber = append(memeber, umem) if usrs[i]["isadmin"].(bool) { adminMember = append(adminMember, umem) } } if org["fullname"].(string) == "/" { continue } if _, err = db.Query(mql, "", org["username"], org["fullname"], true, memeber).Do(); err != nil { fmt.Printf(err.Error()) } // Update org grpset if _, err = db.Query("update /matrix/ldap set grpset = grpset + '" + org["fullname"].(string) + "' where fullname = '" + org["fullname"].(string) + "'").Do(); err != nil { fmt.Printf(err.Error()) } } // Create admin group if _, err = db.Query(mql, "", "admin", "/admin", false, adminMember).Do(); err != nil { fmt.Printf(err.Error()) } for _, ufn := range adminMember { if _, err = db.Query("update /matrix/ldap set grpset = grpset + '/admin' where fullname = '" + ufn[1:] + "'").Do(); err != nil { fmt.Printf(err.Error()) } } } func buildTree(parent string, left int, tree []*lp.Object) int { right := left + 1 // get children children := make([]*lp.Object, 0) for _, c := range tree { if c.Parent == parent { children = append(children, c) } } // range children to recursive for _, n := range children { right = buildTree(n.FullName, right, tree) } // set node left and right for i, c := range tree { if c.FullName == parent { tree[i].Lft = left tree[i].Rgt = right } } return right + 1 } // GetRandomString generate random string by specify chars. // E:\Develop\golocal\src\janesware.com\web\modules\base\tool.go func getRandomString(n int, alphabets ...byte) string { const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" var bytes = make([]byte, n) _, _ = rand.Read(bytes) for i, b := range bytes { if len(alphabets) == 0 { bytes[i] = alphanum[b%byte(len(alphanum))] } else { bytes[i] = alphabets[b%byte(len(alphabets))] } } return string(bytes) } // http://code.google.com/p/go/source/browse/pbkdf2/pbkdf2.go?repo=crypto // E:\Develop\golocal\src\janesware.com\web\modules\base\tool.go func PBKDF2(password, salt []byte, iter, keyLen int, h func() hash.Hash) []byte { prf := hmac.New(h, password) hashLen := prf.Size() numBlocks := (keyLen + hashLen - 1) / hashLen var buf [4]byte dk := make([]byte, 0, numBlocks*hashLen) U := make([]byte, hashLen) for block := 1; block <= numBlocks; block++ { // N.B.: || means concatenation, ^ means XOR // for each block T_i = U_1 ^ U_2 ^ ... ^ U_iter // U_1 = PRF(password, salt || uint(i)) prf.Reset() prf.Write(salt) buf[0] = byte(block >> 24) buf[1] = byte(block >> 16) buf[2] = byte(block >> 8) buf[3] = byte(block) prf.Write(buf[:4]) dk = prf.Sum(dk) T := dk[len(dk)-hashLen:] copy(U, T) // U_n = PRF(password, U_(n-1)) for n := 2; n <= iter; n++ { prf.Reset() prf.Write(U) U = U[:0] U = prf.Sum(U) for x := range U { T[x] ^= U[x] } } } return dk[:keyLen] } func createObjectFromObject(class string, u *lp.Object, db odb.Client) error { m := make(map[string]interface{}) if err := common.Struct2Map(&u, &m); err != nil { return err } var ( mql string fields []string qms []string values []interface{} ) if len(m) != 0 { for k := range m { if k != "class" { fields = append(fields, k) } } if len(fields) != 0 { sort.Strings(fields) for _, k := range fields { qms = append(qms, "?") values = append(values, m[k]) } mql = fmt.Sprintf(`insert into %s (%s) values (%s)`, class, strings.Join(fields, ", "), strings.Join(qms, ", ")) fmt.Println(mql) fmt.Println( values...) if _, err := db.Query(mql, values...).Do(); err != nil { return err } } } return nil } func getDB() (odb.Client, error) { if db, err := modb.New("ootest"); err != nil { return nil, err } else { return db, nil } }