Skip to content

Commit dde4294

Browse files
authored
refactor: use 63bit hashed IDs instead of previous encoded ids
#27
2 parents d2b4a2f + de70756 commit dde4294

11 files changed

Lines changed: 400 additions & 314 deletions

File tree

bluesky/blueskyapi.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"io"
99
"net/http"
1010
"net/url"
11+
"strconv"
1112
"strings"
1213
"sync"
1314
"time"
@@ -581,6 +582,7 @@ func GetRelationships(pds string, token string, source string, others []string)
581582
}
582583

583584
func AuthorTTB(author User) *bridge.TwitterUser {
585+
id := bridge.BlueSkyToTwitterID(author.DID)
584586
return &bridge.TwitterUser{
585587
ProfileSidebarFillColor: "e0ff92",
586588
Name: func() string {
@@ -599,8 +601,8 @@ func AuthorTTB(author User) *bridge.TwitterUser {
599601
ContributorsEnabled: false,
600602
URL: "",
601603
UtcOffset: nil,
602-
ID: bridge.BlueSkyToTwitterID(author.DID),
603-
IDStr: bridge.BlueSkyToTwitterID(author.DID).String(),
604+
ID: *id,
605+
IDStr: strconv.FormatInt(*id, 10),
604606
ProfileUseBackgroundImage: false,
605607
ListedCount: 0,
606608
ProfileTextColor: "000000",
@@ -857,15 +859,15 @@ func UpdateStatus(pds string, token string, my_did string, status string, in_rep
857859
// add mentions to the facets
858860
if err == nil {
859861
for _, mention := range mentions {
860-
var mentionDID string
862+
var mentionDID *string
861863
for _, user := range mentionedUsers {
862864
if user.ScreenName == mention.Item {
863-
mentionDID = bridge.TwitterIDToBlueSky(*user.ID) // efficency is poor
865+
mentionDID, _ = bridge.TwitterIDToBlueSky(&user.ID) // efficency is poor
864866
break
865867
}
866868
}
867869

868-
if mentionDID == "" {
870+
if mentionDID == nil {
869871
continue
870872
}
871873

@@ -877,7 +879,7 @@ func UpdateStatus(pds string, token string, my_did string, status string, in_rep
877879
Features: []Feature{
878880
{
879881
Type: "app.bsky.richtext.facet#mention",
880-
Did: mentionDID,
882+
Did: *mentionDID,
881883
},
882884
},
883885
})

bridge/bridge.go

Lines changed: 104 additions & 170 deletions
Large diffs are not rendered by default.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package bridge
1+
package cryption
22

33
import (
44
"crypto/aes"

db_controller/db_controller.go

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@ import (
44
"fmt"
55
"os"
66
"path/filepath"
7+
"time"
8+
9+
"strconv"
710

8-
"github.com/Preloading/MastodonTwitterAPI/bridge"
911
"github.com/Preloading/MastodonTwitterAPI/config"
12+
authcrypt "github.com/Preloading/MastodonTwitterAPI/cryption"
1013
"github.com/google/uuid"
1114
"gorm.io/driver/mysql"
1215
"gorm.io/driver/postgres"
@@ -54,6 +57,13 @@ type Token struct {
5457
RefreshExpiry float64 `gorm:"type:float;not null"`
5558
}
5659

60+
type TwitterIDs struct {
61+
BlueskyID string `gorm:"type:string;not null"`
62+
TwitterID string `gorm:"type:string;primaryKey;not null"` // Ensure this has a unique constraint
63+
ReposterDid *string `gorm:"type:string"`
64+
DateCreated *time.Time `gorm:"type:timestamp"`
65+
}
66+
5767
type MessageContext struct {
5868
UserDid string `gorm:"type:string;primaryKey;not null"`
5969
TokenUUID string `gorm:"type:string;primaryKey;not null"`
@@ -90,6 +100,7 @@ func InitDB(cfg config.Config) {
90100
// Auto-migrate the schema
91101
db.AutoMigrate(&Token{})
92102
db.AutoMigrate(&MessageContext{})
103+
db.AutoMigrate(&TwitterIDs{})
93104
}
94105

95106
// StoreToken stores an encrypted access token and refresh token in the database.
@@ -124,12 +135,12 @@ func StoreToken(did string, pds string, accessToken string, refreshToken string,
124135
}
125136

126137
func UpdateToken(uuid string, did string, pds string, accessToken string, refreshToken string, encryptionKey string, accessExpiry float64, refreshExpiry float64) (*string, error) {
127-
encryptedAccess, err := bridge.Encrypt(accessToken, encryptionKey)
138+
encryptedAccess, err := authcrypt.Encrypt(accessToken, encryptionKey)
128139
if err != nil {
129140
return nil, fmt.Errorf("failed to encrypt access token: %v", err)
130141
}
131142

132-
encryptedRefresh, err := bridge.Encrypt(refreshToken, encryptionKey)
143+
encryptedRefresh, err := authcrypt.Encrypt(refreshToken, encryptionKey)
133144
if err != nil {
134145
return nil, fmt.Errorf("failed to encrypt refresh token: %v", err)
135146
}
@@ -168,15 +179,63 @@ func GetToken(did string, tokenUUID string, encryptionKey string) (*string, *str
168179
return nil, nil, nil, nil, nil, err
169180
}
170181

171-
accessToken, err := bridge.Decrypt(token.EncryptedAccessToken, encryptionKey)
182+
accessToken, err := authcrypt.Decrypt(token.EncryptedAccessToken, encryptionKey)
172183
if err != nil {
173184
return nil, nil, nil, nil, nil, err
174185
}
175186

176-
refreshToken, err := bridge.Decrypt(token.EncryptedRefreshToken, encryptionKey)
187+
refreshToken, err := authcrypt.Decrypt(token.EncryptedRefreshToken, encryptionKey)
177188
if err != nil {
178189
return nil, nil, nil, nil, nil, err
179190
}
180191

181192
return &accessToken, &refreshToken, &token.AccessExpiry, &token.RefreshExpiry, &token.UserPDS, nil
182193
}
194+
195+
// Stores ID data in the database.
196+
// @params: twitterID, blueskyID, dateCreated, reposterDid
197+
// @results: error
198+
func StoreTwitterIdInDatabase(twitterID *int64, blueskyId string, dateCreated *time.Time, reposterDid *string) error {
199+
if twitterID == nil {
200+
return fmt.Errorf("twitterID is nil")
201+
}
202+
203+
storedData := TwitterIDs{
204+
TwitterID: strconv.FormatInt(*twitterID, 10), // Convert *int64 to string
205+
BlueskyID: blueskyId,
206+
DateCreated: dateCreated,
207+
ReposterDid: reposterDid,
208+
}
209+
210+
result := db.Clauses(clause.OnConflict{
211+
Columns: []clause.Column{
212+
{Name: "twitter_id"},
213+
},
214+
UpdateAll: true,
215+
}).Create(&storedData)
216+
217+
if result.Error != nil {
218+
// If there's an error, try updating the existing record
219+
fmt.Println("Error:", result.Error)
220+
panic(result.Error)
221+
//return db.Model(&TwitterIDs{}).Where("twitter_id = ?", strconv.FormatUint(twitterID, 10)).Updates(storedData).Error
222+
}
223+
224+
return nil
225+
}
226+
227+
// Gets a twitter id from the database
228+
// @params: twitterID
229+
// @results: blueskyID, dateCreated, reposterDid, error
230+
func GetTwitterIDFromDatabase(twitterID *int64) (*string, *time.Time, *string, error) {
231+
if twitterID == nil {
232+
return nil, nil, nil, fmt.Errorf("twitterID is nil")
233+
}
234+
235+
var blueskyID TwitterIDs
236+
if err := db.Where("twitter_id = ?", strconv.FormatInt(*twitterID, 10)).First(&blueskyID).Error; err != nil {
237+
return nil, nil, nil, err
238+
}
239+
240+
return &blueskyID.BlueskyID, blueskyID.DateCreated, blueskyID.ReposterDid, nil
241+
}

twitterv1/auth.go

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
blueskyapi "github.com/Preloading/MastodonTwitterAPI/bluesky"
1111
"github.com/Preloading/MastodonTwitterAPI/bridge"
12+
"github.com/Preloading/MastodonTwitterAPI/cryption"
1213
"github.com/Preloading/MastodonTwitterAPI/db_controller"
1314
"github.com/gofiber/fiber/v2"
1415
)
@@ -31,18 +32,18 @@ func access_token(c *fiber.Ctx) error {
3132
}
3233

3334
// Our bluesky authentication was sucessful! Now we should store the auth info, encryted, in the DB
34-
encryptionkey, err := bridge.GenerateKey()
35+
encryptionkey, err := cryption.GenerateKey()
3536
if err != nil {
3637
fmt.Println("Error:", err)
3738
return c.SendStatus(500)
3839
}
3940

40-
access_token_expiry, err := bridge.GetJWTTokenExpirationUnix(res.AccessJwt)
41+
access_token_expiry, err := cryption.GetJWTTokenExpirationUnix(res.AccessJwt)
4142
if err != nil {
4243
fmt.Println("Error:", err)
4344
return c.SendStatus(500)
4445
}
45-
refresh_token_expiry, err := bridge.GetJWTTokenExpirationUnix(res.RefreshJwt)
46+
refresh_token_expiry, err := cryption.GetJWTTokenExpirationUnix(res.RefreshJwt)
4647
if err != nil {
4748
fmt.Println("Error:", err)
4849
return c.SendStatus(500)
@@ -58,9 +59,9 @@ func access_token(c *fiber.Ctx) error {
5859
encryptionkey = strings.ReplaceAll(encryptionkey, "/", "_")
5960
encryptionkey = strings.ReplaceAll(encryptionkey, "=", "") // remove padding
6061

61-
oauth_token := fmt.Sprintf("%s.%s.%s", bridge.Base64URLEncode(res.DID), bridge.Base64URLEncode(*uuid), encryptionkey)
62+
oauth_token := fmt.Sprintf("%s.%s.%s", cryption.Base64URLEncode(res.DID), cryption.Base64URLEncode(*uuid), encryptionkey)
6263

63-
return c.SendString(fmt.Sprintf("oauth_token=%s&oauth_token_secret=%s&user_id=%s&screen_name=twitterapi&x_auth_expires=%f", oauth_token, oauth_token, bridge.BlueSkyToTwitterID(res.DID).String(), *access_token_expiry))
64+
return c.SendString(fmt.Sprintf("oauth_token=%s&oauth_token_secret=%s&user_id=%s&screen_name=twitterapi&x_auth_expires=%f", oauth_token, oauth_token, fmt.Sprintf("%d", bridge.BlueSkyToTwitterID(res.DID)), *access_token_expiry))
6465
}
6566
// We have an unknown request. huh. Probably registration, i'll find a way to send an error msg for that later, as registration is out of scope.
6667
return c.SendStatus(501)
@@ -109,14 +110,14 @@ func GetAuthFromReq(c *fiber.Ctx) (*string, *string, *string, *string, error) {
109110
// Replace URL-friendly characters with original base64 characters
110111

111112
// Get user DID
112-
userDID, err := bridge.Base64URLDecode(oauthTokenSegments[0])
113+
userDID, err := cryption.Base64URLDecode(oauthTokenSegments[0])
113114

114115
if err != nil {
115116
return nil, &fallbackRoute, nil, nil, err
116117
}
117118

118119
// Get our token UUID. This is used to look up the token in the database.
119-
tokenUUID, err := bridge.Base64URLDecode(oauthTokenSegments[1])
120+
tokenUUID, err := cryption.Base64URLDecode(oauthTokenSegments[1])
120121

121122
if err != nil {
122123
return nil, &fallbackRoute, nil, nil, err
@@ -157,11 +158,11 @@ func GetAuthFromReq(c *fiber.Ctx) (*string, *string, *string, *string, error) {
157158

158159
accessJwt = &new_auth.AccessJwt
159160

160-
access_token_expiry, err := bridge.GetJWTTokenExpirationUnix(new_auth.AccessJwt)
161+
access_token_expiry, err := cryption.GetJWTTokenExpirationUnix(new_auth.AccessJwt)
161162
if err != nil {
162163
return nil, &fallbackRoute, nil, nil, errors.New("failed to get access token expiry")
163164
}
164-
refresh_token_expiry, err := bridge.GetJWTTokenExpirationUnix(new_auth.RefreshJwt)
165+
refresh_token_expiry, err := cryption.GetJWTTokenExpirationUnix(new_auth.RefreshJwt)
165166
if err != nil {
166167
return nil, &fallbackRoute, nil, nil, errors.New("failed to get refresh token expiry")
167168
}

twitterv1/connect.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ func GetMyActivity(c *fiber.Ctx) error {
8989
twitterNotifications = append(twitterNotifications, bridge.MyActivity{
9090
Action: "follow",
9191
CreatedAt: bridge.TwitterTimeConverter(notification.IndexedAt),
92-
ID: bridge.BlueSkyToTwitterID(notification.URI),
92+
ID: *bridge.BlueSkyToTwitterID(notification.URI),
9393
Sources: sources,
9494
})
9595
case "like":
@@ -133,7 +133,7 @@ func GetMyActivity(c *fiber.Ctx) error {
133133
twitterNotifications = append(twitterNotifications, bridge.MyActivity{
134134
Action: "favorite",
135135
CreatedAt: bridge.TwitterTimeConverter(notification.IndexedAt),
136-
ID: bridge.BlueSkyToTwitterID(notificationId),
136+
ID: *bridge.BlueSkyToTwitterID(notificationId),
137137
Sources: sources,
138138
Targets: []bridge.Tweet{likedTweet},
139139
})
@@ -178,7 +178,7 @@ func GetMyActivity(c *fiber.Ctx) error {
178178
twitterNotifications = append(twitterNotifications, bridge.MyActivity{
179179
Action: "retweet",
180180
CreatedAt: bridge.TwitterTimeConverter(notification.IndexedAt),
181-
ID: bridge.BlueSkyToTwitterID(notificationId),
181+
ID: *bridge.BlueSkyToTwitterID(notificationId),
182182
Sources: sources,
183183
TargetObjects: []bridge.Tweet{retweetedTweet},
184184
})

twitterv1/discover.go

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ package twitterv1
22

33
import (
44
"fmt"
5-
"math/big"
65
"net/url"
6+
"strconv"
77
"strings"
88
"time"
99

@@ -32,12 +32,11 @@ func InternalSearch(c *fiber.Ctx) error {
3232
max_id := c.Query("max_id")
3333
var until *time.Time
3434
if max_id != "" {
35-
maxIDBigInt := new(big.Int)
36-
maxIDBigInt, ok := maxIDBigInt.SetString(max_id, 10)
37-
if !ok {
35+
maxIDInt, err := strconv.ParseInt(max_id, 10, 64)
36+
if err != nil {
3837
return c.Status(fiber.StatusBadRequest).SendString("Invalid max_id")
3938
}
40-
_, until, _, err = bridge.TwitterMsgIdToBluesky(maxIDBigInt)
39+
_, until, _, err = bridge.TwitterMsgIdToBluesky(&maxIDInt)
4140
if err != nil {
4241
return c.Status(fiber.StatusBadRequest).SendString("Invalid max_id")
4342
}
@@ -46,12 +45,11 @@ func InternalSearch(c *fiber.Ctx) error {
4645
var since *time.Time
4746
since_id := c.Query("since_id")
4847
if since_id != "" {
49-
sinceIDBigInt := new(big.Int)
50-
sinceIDBigInt, ok := sinceIDBigInt.SetString(since_id, 10)
51-
if !ok {
48+
sinceIDInt, err := strconv.ParseInt(since_id, 10, 64)
49+
if err != nil {
5250
return c.Status(fiber.StatusBadRequest).SendString("Invalid since_id")
5351
}
54-
_, until, _, err = bridge.TwitterMsgIdToBluesky(sinceIDBigInt)
52+
_, until, _, err = bridge.TwitterMsgIdToBluesky(&sinceIDInt)
5553
if err != nil {
5654
return c.Status(fiber.StatusBadRequest).SendString("Invalid since_id")
5755
}

0 commit comments

Comments
 (0)