|
5 | 5 | package migrations |
6 | 6 |
|
7 | 7 | import ( |
8 | | - "encoding/base32" |
9 | | - "fmt" |
10 | | - "strings" |
11 | | - |
12 | | - "code.gitea.io/gitea/modules/timeutil" |
13 | | - |
14 | | - "github.com/tstranex/u2f" |
15 | 8 | "xorm.io/xorm" |
16 | | - "xorm.io/xorm/schemas" |
17 | 9 | ) |
18 | 10 |
|
19 | 11 | func increaseCredentialIDTo410(x *xorm.Engine) error { |
20 | | - // Create webauthnCredential table |
21 | | - type webauthnCredential struct { |
22 | | - ID int64 `xorm:"pk autoincr"` |
23 | | - Name string |
24 | | - LowerName string `xorm:"unique(s)"` |
25 | | - UserID int64 `xorm:"INDEX unique(s)"` |
26 | | - CredentialID string `xorm:"INDEX VARCHAR(410)"` // CredentalID in U2F is at most 255bytes / 5 * 8 = 408 - add a few extra characters for safety |
27 | | - PublicKey []byte |
28 | | - AttestationType string |
29 | | - AAGUID []byte |
30 | | - SignCount uint32 `xorm:"BIGINT"` |
31 | | - CloneWarning bool |
32 | | - CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` |
33 | | - UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` |
34 | | - } |
35 | | - if err := x.Sync2(&webauthnCredential{}); err != nil { |
36 | | - return err |
37 | | - } |
38 | | - |
39 | | - switch x.Dialect().URI().DBType { |
40 | | - case schemas.MYSQL: |
41 | | - _, err := x.Exec("ALTER TABLE webauthn_credential MODIFY COLUMN credential_id VARCHAR(410)") |
42 | | - if err != nil { |
43 | | - return err |
44 | | - } |
45 | | - case schemas.ORACLE: |
46 | | - _, err := x.Exec("ALTER TABLE webauthn_credential MODIFY credential_id VARCHAR(410)") |
47 | | - if err != nil { |
48 | | - return err |
49 | | - } |
50 | | - case schemas.MSSQL: |
51 | | - // This column has an index on it. I could write all of the code to attempt to change the index OR |
52 | | - // I could just use recreate table. |
53 | | - sess := x.NewSession() |
54 | | - if err := sess.Begin(); err != nil { |
55 | | - _ = sess.Close() |
56 | | - return err |
57 | | - } |
58 | | - |
59 | | - if err := recreateTable(sess, new(webauthnCredential)); err != nil { |
60 | | - _ = sess.Close() |
61 | | - return err |
62 | | - } |
63 | | - if err := sess.Commit(); err != nil { |
64 | | - _ = sess.Close() |
65 | | - return err |
66 | | - } |
67 | | - if err := sess.Close(); err != nil { |
68 | | - return err |
69 | | - } |
70 | | - case schemas.POSTGRES: |
71 | | - _, err := x.Exec("ALTER TABLE webauthn_credential ALTER COLUMN credential_id TYPE VARCHAR(410)") |
72 | | - if err != nil { |
73 | | - return err |
74 | | - } |
75 | | - default: |
76 | | - // SQLite doesn't support ALTER COLUMN, and it already makes String _TEXT_ by default so no migration needed |
77 | | - // nor is there any need to re-migrate |
78 | | - return nil |
79 | | - } |
80 | | - |
81 | | - exist, err := x.IsTableExist("u2f_registration") |
82 | | - if err != nil { |
83 | | - return err |
84 | | - } |
85 | | - if !exist { |
86 | | - return nil |
87 | | - } |
88 | | - |
89 | | - // Now migrate the old u2f registrations to the new format |
90 | | - type u2fRegistration struct { |
91 | | - ID int64 `xorm:"pk autoincr"` |
92 | | - Name string |
93 | | - UserID int64 `xorm:"INDEX"` |
94 | | - Raw []byte |
95 | | - Counter uint32 `xorm:"BIGINT"` |
96 | | - CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` |
97 | | - UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` |
98 | | - } |
99 | | - |
100 | | - var start int |
101 | | - regs := make([]*u2fRegistration, 0, 50) |
102 | | - for { |
103 | | - err := x.OrderBy("id").Limit(50, start).Find(®s) |
104 | | - if err != nil { |
105 | | - return err |
106 | | - } |
107 | | - |
108 | | - for _, reg := range regs { |
109 | | - parsed := new(u2f.Registration) |
110 | | - err = parsed.UnmarshalBinary(reg.Raw) |
111 | | - if err != nil { |
112 | | - continue |
113 | | - } |
114 | | - |
115 | | - cred := &webauthnCredential{} |
116 | | - has, err := x.ID(reg.ID).Where("id = ? AND user_id = ?", reg.ID, reg.UserID).Get(cred) |
117 | | - if err != nil { |
118 | | - return fmt.Errorf("unable to get webauthn_credential[%d]. Error: %v", reg.ID, err) |
119 | | - } |
120 | | - if !has { |
121 | | - continue |
122 | | - } |
123 | | - remigratedCredID := base32.HexEncoding.EncodeToString(parsed.KeyHandle) |
124 | | - if cred.CredentialID == remigratedCredID || (!strings.HasPrefix(remigratedCredID, cred.CredentialID) && cred.CredentialID != "") { |
125 | | - continue |
126 | | - } |
127 | | - |
128 | | - cred.CredentialID = remigratedCredID |
129 | | - |
130 | | - _, err = x.ID(cred.ID).Update(cred) |
131 | | - if err != nil { |
132 | | - return err |
133 | | - } |
134 | | - } |
135 | | - |
136 | | - if len(regs) < 50 { |
137 | | - break |
138 | | - } |
139 | | - start += 50 |
140 | | - regs = regs[:0] |
141 | | - } |
| 12 | + // no-op |
| 13 | + // v208 was completely wrong |
| 14 | + // So now we have to no-op again. |
142 | 15 |
|
143 | 16 | return nil |
144 | 17 | } |
0 commit comments