Compare commits

...

11 commits

Author SHA1 Message Date
d983bfb9a3 improve error handling for listen 2022-12-29 17:45:22 -08:00
097e95bdb1 Add version 17 migration
Fixes #15
2022-12-18 22:00:58 -08:00
fc7a556b5d download dependant artifacts via the gitlab API since inter-project dependencies are now a premium feature 2022-10-25 17:59:02 -07:00
10dab5a5c9 allow updating more of the profile 2022-10-25 16:17:44 -07:00
finn
3e33f0a3f7 add --overwrite option to signaldctl account link 2022-08-29 11:57:45 -07:00
Andrew Ferrazzutti
5470eb90d9 Avoid more constraint violations during db-move 2022-08-16 17:01:56 +00:00
finn
1ced8e01b2 bump protocol 2022-08-16 09:57:10 -07:00
finn
5e52e5f3bd deb build cut first character (v) out of version string 2022-08-16 09:32:40 -07:00
Andrew Ferrazzutti
4178a582e8 Refactor more migration functions 2022-08-15 17:36:01 -04:00
Andrew Ferrazzutti
67a7576e24 Refactor migration functions & messages
Ensure that success & error migration logs use the same description text
for the migration step that they refer to.
2022-08-12 21:05:12 +00:00
Andrew Ferrazzutti
dd208b6e82 Exclude missing accounts from contact migration
Otherwise, moveContacts fails with a foreign key constraint violation.
2022-08-12 16:33:12 -04:00
9 changed files with 138 additions and 5669 deletions

View file

@ -62,27 +62,22 @@ test sqlite to postgres:
.build-deb:
stage: build
image: debian:buster
script:
before_script:
- echo deb http://deb.debian.org/debian buster-backports main > /etc/apt/sources.list.d/backports.list
- apt-get update
- apt-get install -y -t buster-backports git-buildpackage dh-golang bash-completion golang-any golang-github-spf13-cobra-dev golang-github-spf13-viper-dev golang-github-google-uuid-dev golang-github-mattn-go-sqlite3-dev golang-github-lib-pq-dev golang-github-satori-go.uuid-dev
- apt-get install -y -t buster-backports git-buildpackage dh-golang bash-completion golang-any golang-github-spf13-cobra-dev golang-github-spf13-viper-dev golang-github-google-uuid-dev golang-github-mattn-go-sqlite3-dev golang-github-lib-pq-dev golang-github-satori-go.uuid-dev wget unzip
- wget -O golang-github-mdp-qrterminal.zip --quiet "https://gitlab.com/api/v4/projects/signald%2Flibraries%2Fgolang-github-mdp-qrterminal/jobs/artifacts/master/download?job=build"
- wget -O golang-github-jedib0t-go-pretty.zip --quiet "https://gitlab.com/api/v4/projects/signald%2Flibraries%2Fgolang-github-jedib0t-go-pretty/jobs/artifacts/master/download?job=build"
- for z in *.zip; do unzip $z; done
- apt-get install -y ./*.deb && rm -vf *.deb
script:
- 'sed -i "s/^Architecture:.*/Architecture: ${ARCH}/g" debian/control'
- go run ./cmd/signaldctl doc -o man
- go run ./cmd/signaldctl completion bash > debian/package.bash-completion
- ls *.1 > debian/manpages
- gbp dch --ignore-branch --debian-tag="%(version)s" --git-author --new-version="$(./version.sh)"
- gbp dch --ignore-branch --debian-tag="%(version)s" --git-author --new-version="$(./version.sh | cut -c2-)"
- dpkg-buildpackage -us -uc -b
- mv ../*.deb .
needs:
- project: signald/libraries/golang-github-mdp-qrterminal
job: build
ref: master
artifacts: true
- project: signald/libraries/golang-github-jedib0t-go-pretty
job: build
ref: master
artifacts: true
variables:
SIGNALDCTL_PUBLIC_DOC_MODE: "on"
artifacts:

View file

@ -34,6 +34,7 @@ import (
var (
testing bool
deviceName string
overwrite bool
LinkAccountCmd = &cobra.Command{
Use: "link",
@ -80,6 +81,7 @@ var (
finishReq := v1.FinishLinkRequest{
DeviceName: deviceName,
SessionId: response.SessionId,
Overwrite: overwrite,
}
_, err = finishReq.Submit(common.Signald)
@ -99,4 +101,5 @@ func init() {
}
LinkAccountCmd.Flags().BoolVarP(&testing, "testing", "t", false, "use the Signal testing server")
LinkAccountCmd.Flags().StringVarP(&deviceName, "device-name", "n", name, "the name of this device. shown to other devices on the signal account")
LinkAccountCmd.Flags().BoolVar(&overwrite, "overwrite", false, "if an account with the same id already exists in signald's database, delete it before linking")
}

View file

@ -27,10 +27,14 @@ import (
var (
account string
name string
avatar string
emoji string
about string
SetProfileCmd = &cobra.Command{
Use: "set-profile name",
Short: "updates the profile data with a new name",
Use: "set-profile [name]",
Short: "update an account's profile data",
PreRun: func(cmd *cobra.Command, args []string) {
if account == "" {
account = config.Config.DefaultAccount
@ -39,16 +43,19 @@ var (
common.Must(cmd.Help())
log.Fatal("No account specified. Please specify with --account or set a default")
}
if len(args) != 1 {
common.Must(cmd.Help())
log.Fatal("must specify a name")
if len(args) > 0 {
name = args[0]
}
},
Run: func(_ *cobra.Command, args []string) {
Run: func(_ *cobra.Command, _ []string) {
go common.Signald.Listen(nil)
req := v1.SetProfile{
Account: account,
Name: args[0],
Account: account,
Name: name,
AvatarFile: avatar,
Emoji: emoji,
About: about,
}
err := req.Submit(common.Signald)
if err != nil {
@ -61,4 +68,7 @@ var (
func init() {
SetProfileCmd.Flags().StringVarP(&account, "account", "a", "", "the signald account to use")
SetProfileCmd.Flags().StringVarP(&avatar, "avatar", "A", "", "path to avatar file")
SetProfileCmd.Flags().StringVar(&emoji, "emoji", "", "an emoji to be shown next to the about section")
SetProfileCmd.Flags().StringVar(&about, "about", "", "profile about section")
}

View file

@ -33,6 +33,7 @@ var (
{InstalledRank: 4, Version: "14", Description: "multiple identity keys per account", Script: "V14__multiple_identity_keys_per_account.sql", Checksum: -1635788950},
{InstalledRank: 5, Version: "15", Description: "profiles tables", Script: "V15__profiles_tables.sql", Checksum: 809686180},
{InstalledRank: 6, Version: "16", Description: "destination uuid in envelope", Script: "V16__destination_uuid_in_envelope.sql", Checksum: 357656854},
{InstalledRank: 7, Version: "17", Description: "update server ca", Script: "V17__update_server_ca.sql", Checksum: 1647934070},
}
sqlitePath string
@ -60,7 +61,7 @@ var (
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
RunE: func(cmd *cobra.Command, args []string) (err error) {
source, err := sql.Open("sqlite3", sqlitePath)
if err != nil {
return err
@ -93,107 +94,37 @@ var (
}
log.Println("created schema")
if err := moveAccounts(source, dest); err != nil {
log.Println("error moving accounts table")
return err
migrate := func(fn func(*sql.DB, *sql.DB) error, targetName string) {
if err = fn(source, dest); err != nil {
log.Println("error moving", targetName)
panic(err)
}
log.Println("moved", targetName)
}
log.Println("moved accounts table")
defer func() {
if r := recover(); r != nil && r != err {
// If r is something other than the error returned via the named return, re-panic it
panic(r)
}
}()
if err := moveRecipients(source, dest); err != nil {
log.Println("error moving recipients table")
return err
}
log.Println("moved recipients table")
if err := movePrekeys(source, dest); err != nil {
log.Println("error moving prekeys table")
return err
}
log.Println("moved prekeys table")
if err := moveSessions(source, dest); err != nil {
log.Println("error moving sessions table")
return err
}
log.Println("moved sessions table")
if err := moveSignedPrekeys(source, dest); err != nil {
log.Println("error moving signed prekeys table")
return err
}
log.Println("moved signed prekeys table")
if err := moveIdentityKeys(source, dest); err != nil {
log.Println("error moving identity keys table")
return err
}
log.Println("moved identity keys table")
if err := moveAccountData(source, dest); err != nil {
log.Println("error moving account data")
return err
}
log.Println("moved account data table")
if err := movePendingAccountData(source, dest); err != nil {
log.Println("error moving pending account data tabe")
return err
}
log.Println("moved pending account data table")
if err := moveSenderKeys(source, dest); err != nil {
log.Println("error moving sender keys table")
return err
}
log.Println("moved sender keys table")
if err := moveSenderKeyShared(source, dest); err != nil {
log.Println("error moving sender key shared table")
return err
}
log.Println("moved sender key shared table")
if err := moveGroups(source, dest); err != nil {
log.Println("error moving groups table")
return err
}
log.Println("moved groups table")
if err := moveGroupCredentials(source, dest); err != nil {
log.Println("error moving group credentials table")
return err
}
log.Println("moved group credentials table")
if err := moveContacts(source, dest); err != nil {
log.Println("error moving group credentials table")
return err
}
log.Println("moved contacts table")
if err := moveProfileKeys(source, dest); err != nil {
log.Println("error moving profile keys table")
return err
}
log.Println("moved profile keys table")
if err := moveProfiles(source, dest); err != nil {
log.Println("error moving profiles tables")
return err
}
log.Println("moved profiles tables")
if err := moveProfileCapabilities(source, dest); err != nil {
log.Println("error moving profile capabilities tables")
return err
}
log.Println("moved profile capabilities tables")
if err := moveProfileBadges(source, dest); err != nil {
log.Println("error moving profile badges tables")
return err
}
log.Println("moved profile badges tables")
migrate(moveAccounts, "accounts table")
migrate(moveRecipients, "recipients table")
migrate(movePrekeys, "prekeys table")
migrate(moveSessions, "sessions table")
migrate(moveSignedPrekeys, "signed prekeys table")
migrate(moveIdentityKeys, "identity keys table")
migrate(moveAccountData, "account data")
migrate(movePendingAccountData, "pending account data table")
migrate(moveSenderKeys, "sender keys table")
migrate(moveSenderKeyShared, "sender key shared table")
migrate(moveGroups, "groups table")
migrate(moveGroupCredentials, "group credentials table")
migrate(moveContacts, "contacts table")
migrate(moveProfileKeys, "profile keys table")
migrate(moveProfiles, "profiles tables")
migrate(moveProfileCapabilities, "profile capabilities tables")
migrate(moveProfileBadges, "profile badges tables")
if err := os.Remove(sqlitePath); err != nil {
log.Println("error deleting sqlite file")
@ -279,7 +210,9 @@ func moveAccounts(source *sql.DB, dest *sql.DB) error {
}
func moveRecipients(source *sql.DB, dest *sql.DB) error {
rows, err := source.Query("SELECT rowid, account_uuid, uuid, e164, registered FROM recipients")
rows, err := source.Query("SELECT rowid, account_uuid, uuid, e164, registered FROM recipients" +
" WHERE account_uuid IN (SELECT DISTINCT uuid FROM accounts)",
)
if err != nil {
return err
}
@ -319,7 +252,9 @@ func moveRecipients(source *sql.DB, dest *sql.DB) error {
}
func movePrekeys(source *sql.DB, dest *sql.DB) error {
rows, err := source.Query("SELECT account_uuid, id, record FROM prekeys")
rows, err := source.Query("SELECT account_uuid, id, record FROM prekeys" +
" WHERE account_uuid IN (SELECT DISTINCT uuid FROM accounts)",
)
if err != nil {
return err
}
@ -344,7 +279,10 @@ func movePrekeys(source *sql.DB, dest *sql.DB) error {
}
func moveSessions(source *sql.DB, dest *sql.DB) error {
rows, err := source.Query("SELECT account_uuid, recipient, device_id, record FROM sessions")
rows, err := source.Query("SELECT account_uuid, recipient, device_id, record FROM sessions" +
" WHERE account_uuid IN (SELECT DISTINCT uuid FROM accounts)" +
" AND recipient IN (SELECT DISTINCT rowid FROM recipients)",
)
if err != nil {
return err
}
@ -379,7 +317,9 @@ func moveSessions(source *sql.DB, dest *sql.DB) error {
}
func moveSignedPrekeys(source *sql.DB, dest *sql.DB) error {
rows, err := source.Query("SELECT account_uuid, id, record FROM signed_prekeys")
rows, err := source.Query("SELECT account_uuid, id, record FROM signed_prekeys" +
" WHERE account_uuid IN (SELECT DISTINCT uuid FROM accounts)",
)
if err != nil {
return err
}
@ -404,7 +344,9 @@ func moveSignedPrekeys(source *sql.DB, dest *sql.DB) error {
}
func moveIdentityKeys(source *sql.DB, dest *sql.DB) error {
rows, err := source.Query("SELECT account_uuid, recipient, identity_key, trust_level, added FROM identity_keys")
rows, err := source.Query("SELECT account_uuid, recipient, identity_key, trust_level, added FROM identity_keys" +
" WHERE account_uuid IN (SELECT DISTINCT uuid FROM accounts)",
)
if err != nil {
return err
}
@ -431,7 +373,9 @@ func moveIdentityKeys(source *sql.DB, dest *sql.DB) error {
}
func moveAccountData(source *sql.DB, dest *sql.DB) error {
rows, err := source.Query("SELECT account_uuid, key, value FROM account_data")
rows, err := source.Query("SELECT account_uuid, key, value FROM account_data" +
" WHERE account_uuid IN (SELECT DISTINCT uuid FROM accounts)",
)
if err != nil {
return err
}
@ -481,7 +425,9 @@ func movePendingAccountData(source *sql.DB, dest *sql.DB) error {
}
func moveSenderKeys(source *sql.DB, dest *sql.DB) error {
rows, err := source.Query("SELECT account_uuid, address, device, distribution_id, record, created_at FROM sender_keys")
rows, err := source.Query("SELECT account_uuid, address, device, distribution_id, record, created_at FROM sender_keys" +
" WHERE account_uuid IN (SELECT DISTINCT uuid FROM accounts)",
)
if err != nil {
return err
}
@ -517,7 +463,9 @@ func moveSenderKeys(source *sql.DB, dest *sql.DB) error {
}
func moveSenderKeyShared(source *sql.DB, dest *sql.DB) error {
rows, err := source.Query("SELECT account_uuid, distribution_id, address, device FROM sender_key_shared")
rows, err := source.Query("SELECT account_uuid, distribution_id, address, device FROM sender_key_shared" +
" WHERE account_uuid IN (SELECT DISTINCT uuid FROM accounts)",
)
if err != nil {
return err
}
@ -553,7 +501,9 @@ func moveSenderKeyShared(source *sql.DB, dest *sql.DB) error {
}
func moveGroups(source *sql.DB, dest *sql.DB) error {
rows, err := source.Query("SELECT rowid, account_uuid, group_id, master_key, revision, last_avatar_fetch, distribution_id, group_info FROM groups")
rows, err := source.Query("SELECT rowid, account_uuid, group_id, master_key, revision, last_avatar_fetch, distribution_id, group_info FROM groups" +
" WHERE account_uuid IN (SELECT DISTINCT uuid FROM accounts)",
)
if err != nil {
return err
}
@ -589,7 +539,10 @@ func moveGroups(source *sql.DB, dest *sql.DB) error {
}
func moveGroupCredentials(source *sql.DB, dest *sql.DB) error {
rows, err := source.Query("SELECT account_uuid, date, credential FROM group_credentials")
rows, err := source.Query("SELECT account_uuid, date, max(credential) FROM group_credentials" +
" WHERE account_uuid IN (SELECT DISTINCT uuid FROM accounts)" +
" GROUP BY account_uuid, date",
)
if err != nil {
return err
}
@ -614,7 +567,10 @@ func moveGroupCredentials(source *sql.DB, dest *sql.DB) error {
}
func moveContacts(source *sql.DB, dest *sql.DB) error {
rows, err := source.Query("SELECT account_uuid, recipient, name, color, profile_key, message_expiration_time, inbox_position FROM contacts")
rows, err := source.Query("SELECT account_uuid, recipient, name, color, profile_key, message_expiration_time, inbox_position FROM contacts" +
" WHERE account_uuid IN (SELECT DISTINCT uuid FROM accounts)" +
" AND recipient IN (SELECT DISTINCT rowid FROM recipients)",
)
if err != nil {
return err
}
@ -647,7 +603,10 @@ func moveContacts(source *sql.DB, dest *sql.DB) error {
}
func moveProfileKeys(source *sql.DB, dest *sql.DB) error {
rows, err := source.Query("SELECT account_uuid, recipient, profile_key, profile_key_credential, request_pending, unidentified_access_mode FROM profile_keys")
rows, err := source.Query("SELECT account_uuid, recipient, profile_key, profile_key_credential, request_pending, unidentified_access_mode FROM profile_keys" +
" WHERE account_uuid IN (SELECT DISTINCT uuid FROM accounts)" +
" AND recipient IN (SELECT DISTINCT rowid FROM recipients)",
)
if err != nil {
return err
}
@ -679,7 +638,10 @@ func moveProfileKeys(source *sql.DB, dest *sql.DB) error {
}
func moveProfiles(source *sql.DB, dest *sql.DB) error {
rows, err := source.Query("SELECT account_uuid, recipient, last_update, given_name, family_name, about, emoji, payment_address, badges FROM profiles")
rows, err := source.Query("SELECT account_uuid, recipient, last_update, given_name, family_name, about, emoji, payment_address, badges FROM profiles" +
" WHERE account_uuid IN (SELECT DISTINCT uuid FROM accounts)" +
" AND recipient IN (SELECT DISTINCT rowid FROM recipients)",
)
if err != nil {
return err
}
@ -714,7 +676,10 @@ func moveProfiles(source *sql.DB, dest *sql.DB) error {
}
func moveProfileCapabilities(source *sql.DB, dest *sql.DB) error {
rows, err := source.Query("SELECT account_uuid, recipient, storage, gv1_migration, sender_key, announcement_group, change_number, stories FROM profile_capabilities")
rows, err := source.Query("SELECT account_uuid, recipient, storage, gv1_migration, sender_key, announcement_group, change_number, stories FROM profile_capabilities" +
" WHERE account_uuid IN (SELECT DISTINCT uuid FROM accounts)" +
" AND recipient IN (SELECT DISTINCT rowid FROM recipients)",
)
if err != nil {
return err
}
@ -748,7 +713,9 @@ func moveProfileCapabilities(source *sql.DB, dest *sql.DB) error {
}
func moveProfileBadges(source *sql.DB, dest *sql.DB) error {
rows, err := source.Query("SELECT account_uuid, id, category, name, description, sprite6 FROM profile_badges")
rows, err := source.Query("SELECT account_uuid, id, category, name, description, sprite6 FROM profile_badges" +
" WHERE account_uuid IN (SELECT DISTINCT uuid FROM accounts)",
)
if err != nil {
return err
}

View file

@ -15,7 +15,6 @@
package session
import (
"github.com/spf13/cobra"
)

File diff suppressed because one or more lines are too long

View file

@ -284,6 +284,13 @@ func mkerr(response client_protocol.BasicResponse) error {
return err
}
return result
case "UnsupportedGroupError":
result := UnsupportedGroupError{}
err := json.Unmarshal(response.Error, &result)
if err != nil {
return err
}
return result
case "UntrustedIdentityError":
result := UntrustedIdentityError{}
err := json.Unmarshal(response.Error, &result)
@ -645,6 +652,15 @@ func (e UnregisteredUserError) Error() string {
return e.Message
}
// UnsupportedGroupError: returned in response to use v1 groups, which are no longer supported
type UnsupportedGroupError struct {
Message string `json:"message,omitempty" yaml:"message,omitempty"`
}
func (e UnsupportedGroupError) Error() string {
return e.Message
}
type UntrustedIdentityError struct {
Identifier string `json:"identifier,omitempty" yaml:"identifier,omitempty"`
IdentityKey **IdentityKey `json:"identity_key,omitempty" yaml:"identity_key,omitempty"`

View file

@ -263,7 +263,7 @@ type GroupLinkInfoRequest struct {
type GroupList struct {
Groups []*JsonGroupV2Info `json:"groups,omitempty" yaml:"groups,omitempty"`
LegacyGroups []*JsonGroupInfo `json:"legacyGroups,omitempty" yaml:"legacyGroups,omitempty"`
LegacyGroups []*JsonGroupInfo `json:"legacyGroups,omitempty" yaml:"legacyGroups,omitempty"` // list of legacy (v1) groups, no longer supported (will always be empty)
}
type GroupMember struct {
@ -492,6 +492,7 @@ type JsonSentTranscriptMessage struct {
ExpirationStartTimestamp int64 `json:"expirationStartTimestamp,omitempty" yaml:"expirationStartTimestamp,omitempty"`
IsRecipientUpdate bool `json:"isRecipientUpdate,omitempty" yaml:"isRecipientUpdate,omitempty"`
Message *JsonDataMessage `json:"message,omitempty" yaml:"message,omitempty"`
Story *StoryMessage `json:"story,omitempty" yaml:"story,omitempty"`
Timestamp int64 `json:"timestamp,omitempty" yaml:"timestamp,omitempty"`
UnidentifiedStatus map[string]string `json:"unidentifiedStatus,omitempty" yaml:"unidentifiedStatus,omitempty"`
}
@ -599,7 +600,8 @@ type Profile struct {
Address *JsonAddress `json:"address,omitempty" yaml:"address,omitempty"`
Avatar string `json:"avatar,omitempty" yaml:"avatar,omitempty"` // path to avatar on local disk
Capabilities *Capabilities `json:"capabilities,omitempty" yaml:"capabilities,omitempty"`
Color string `json:"color,omitempty" yaml:"color,omitempty"` // color of the chat with this user
Color string `json:"color,omitempty" yaml:"color,omitempty"` // color of the chat with this user
ContactName string `json:"contact_name,omitempty" yaml:"contact_name,omitempty"` // The user's name from local contact names
Emoji string `json:"emoji,omitempty" yaml:"emoji,omitempty"`
ExpirationTime int32 `json:"expiration_time,omitempty" yaml:"expiration_time,omitempty"`
InboxPosition int32 `json:"inbox_position,omitempty" yaml:"inbox_position,omitempty"`

View file

@ -99,13 +99,12 @@ func (s *Signald) connect() error {
return nil
}
func (s *Signald) Close() error {
return s.socket.Close()
}
// Listen listens for events from signald
func (s *Signald) Listen(c chan client_protocol.BasicResponse) {
func (s *Signald) Listen(c chan client_protocol.BasicResponse) error {
for {
msg, err := s.readNext()
if err == io.EOF {
@ -113,7 +112,11 @@ func (s *Signald) Listen(c chan client_protocol.BasicResponse) {
if c != nil {
close(c)
}
return
return nil
}
if err != nil {
return err
}
if msg.Type == "unexpected_error" {
@ -175,9 +178,6 @@ func (s *Signald) readNext() (b client_protocol.BasicResponse, err error) {
} else {
err = json.NewDecoder(s.socket).Decode(&b)
}
if err != nil {
log.Println("signald-go: error decoding message from signald:", err)
return
}
return
}