|
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