code.gitea.io/gitea@v1.21.7/models/migrations/v1_16/v189.go (about) 1 // Copyright 2021 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package v1_16 //nolint 5 6 import ( 7 "encoding/binary" 8 "fmt" 9 10 "code.gitea.io/gitea/models/migrations/base" 11 "code.gitea.io/gitea/modules/json" 12 13 "xorm.io/xorm" 14 ) 15 16 func UnwrapLDAPSourceCfg(x *xorm.Engine) error { 17 jsonUnmarshalHandleDoubleEncode := func(bs []byte, v any) error { 18 err := json.Unmarshal(bs, v) 19 if err != nil { 20 ok := true 21 rs := []byte{} 22 temp := make([]byte, 2) 23 for _, rn := range string(bs) { 24 if rn > 0xffff { 25 ok = false 26 break 27 } 28 binary.LittleEndian.PutUint16(temp, uint16(rn)) 29 rs = append(rs, temp...) 30 } 31 if ok { 32 if rs[0] == 0xff && rs[1] == 0xfe { 33 rs = rs[2:] 34 } 35 err = json.Unmarshal(rs, v) 36 } 37 } 38 if err != nil && len(bs) > 2 && bs[0] == 0xff && bs[1] == 0xfe { 39 err = json.Unmarshal(bs[2:], v) 40 } 41 return err 42 } 43 44 // LoginSource represents an external way for authorizing users. 45 type LoginSource struct { 46 ID int64 `xorm:"pk autoincr"` 47 Type int 48 IsActived bool `xorm:"INDEX NOT NULL DEFAULT false"` 49 IsActive bool `xorm:"INDEX NOT NULL DEFAULT false"` 50 Cfg string `xorm:"TEXT"` 51 } 52 53 const ldapType = 2 54 const dldapType = 5 55 56 type WrappedSource struct { 57 Source map[string]any 58 } 59 60 // change lower_email as unique 61 if err := x.Sync(new(LoginSource)); err != nil { 62 return err 63 } 64 65 sess := x.NewSession() 66 defer sess.Close() 67 68 const batchSize = 100 69 for start := 0; ; start += batchSize { 70 sources := make([]*LoginSource, 0, batchSize) 71 if err := sess.Limit(batchSize, start).Where("`type` = ? OR `type` = ?", ldapType, dldapType).Find(&sources); err != nil { 72 return err 73 } 74 if len(sources) == 0 { 75 break 76 } 77 78 for _, source := range sources { 79 wrapped := &WrappedSource{ 80 Source: map[string]any{}, 81 } 82 err := jsonUnmarshalHandleDoubleEncode([]byte(source.Cfg), &wrapped) 83 if err != nil { 84 return fmt.Errorf("failed to unmarshal %s: %w", source.Cfg, err) 85 } 86 if wrapped.Source != nil && len(wrapped.Source) > 0 { 87 bs, err := json.Marshal(wrapped.Source) 88 if err != nil { 89 return err 90 } 91 source.Cfg = string(bs) 92 if _, err := sess.ID(source.ID).Cols("cfg").Update(source); err != nil { 93 return err 94 } 95 } 96 } 97 } 98 99 if _, err := x.SetExpr("is_active", "is_actived").Update(&LoginSource{}); err != nil { 100 return fmt.Errorf("SetExpr Update failed: %w", err) 101 } 102 103 if err := sess.Begin(); err != nil { 104 return err 105 } 106 if err := base.DropTableColumns(sess, "login_source", "is_actived"); err != nil { 107 return err 108 } 109 110 return sess.Commit() 111 }