-
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #22 from rusq/v120-migration
Add creds migration and introduce -logout
- Loading branch information
Showing
7 changed files
with
199 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"fmt" | ||
"os" | ||
|
||
tds "github.com/gotd/td/session" | ||
|
||
"github.com/rusq/wipemychat/internal/session" | ||
) | ||
|
||
const v1signature = `{"Version":1` | ||
|
||
// migratev120 migrates session file from v1 to v1.2.0+ (enables encryption). | ||
// sessfile is the path to the session file. It returns true if the file was | ||
// migrated, false if it was already migrated or invalid. | ||
func migratev120(sessfile string) (bool, error) { | ||
f, err := os.Open(sessfile) | ||
if err != nil { | ||
if os.IsNotExist(err) { | ||
return false, nil | ||
} | ||
return false, err | ||
} | ||
defer f.Close() | ||
if f, err := f.Stat(); err != nil { | ||
return false, err | ||
} else if f.Size() == 0 { | ||
return false, nil | ||
} | ||
b := make([]byte, len(v1signature)) | ||
if n, err := f.Read(b); err != nil { | ||
return false, fmt.Errorf("failed to read session file: %w", err) | ||
} else if n != len(v1signature) { | ||
return false, fmt.Errorf("invalid session file") | ||
} | ||
|
||
if !bytes.Equal(b[:], []byte(v1signature)) { | ||
// already migrated or invalid | ||
return false, nil | ||
} | ||
// needs to be migrated | ||
if err := f.Close(); err != nil { | ||
return false, fmt.Errorf("close error: %w", err) | ||
} | ||
v1loader := tds.FileStorage{Path: sessfile} | ||
sess, err := v1loader.LoadSession(context.Background()) | ||
if err != nil { | ||
return false, fmt.Errorf("failed to load session: %w", err) | ||
} | ||
|
||
// overwrite with new version | ||
v120loader := session.FileStorage{Path: sessfile} | ||
if err := v120loader.StoreSession(context.Background(), sess); err != nil { | ||
return false, fmt.Errorf("failed to save session: %w", err) | ||
} | ||
return true, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"context" | ||
"io" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/rusq/wipemychat/internal/session" | ||
) | ||
|
||
func copyfile(t *testing.T, src, dst string) error { | ||
t.Helper() | ||
sf, err := os.Open(src) | ||
if err != nil { | ||
t.Fatalf("source: %s", err) | ||
} | ||
defer sf.Close() | ||
df, err := os.Create(dst) | ||
if err != nil { | ||
t.Fatalf("destination: %s", err) | ||
} | ||
defer df.Close() | ||
if _, err := io.Copy(df, sf); err != nil { | ||
t.Fatalf("copy: %s", err) | ||
} | ||
return nil | ||
} | ||
|
||
func Test_migratev120(t *testing.T) { | ||
type args struct { | ||
sessfile string | ||
} | ||
tests := []struct { | ||
name string | ||
args args | ||
want bool | ||
wantErr bool | ||
}{ | ||
{ | ||
name: "migrates v1 file", | ||
args: args{sessfile: "testdata/testsessionv100.dat"}, | ||
want: true, | ||
}, | ||
{ | ||
name: "doesn't touch v1.20 file", | ||
args: args{sessfile: "testdata/testsessionv120.dat"}, | ||
want: false, | ||
}, | ||
{ | ||
name: "invalid file", | ||
args: args{sessfile: "testdata/invalidsession.dat"}, | ||
want: false, | ||
wantErr: true, | ||
}, | ||
} | ||
for _, tt := range tests { | ||
t.Run(tt.name, func(t *testing.T) { | ||
// substitute the source file with it's copy in a temporary directory | ||
tmpdir := t.TempDir() | ||
srcfilename := filepath.Base(tt.args.sessfile) | ||
dstfile := filepath.Join(tmpdir, srcfilename) | ||
copyfile(t, tt.args.sessfile, filepath.Join(tmpdir, srcfilename)) | ||
migrated, err := migratev120(dstfile) | ||
if (err != nil) != tt.wantErr { | ||
t.Errorf("migratev120() error = %v, wantErr %v", err, tt.wantErr) | ||
return | ||
} | ||
if migrated != tt.want { | ||
t.Errorf("migratev120() = %v, want %v", migrated, tt.want) | ||
} | ||
if migrated { | ||
// verify the file is valid v1.20 | ||
sess := session.FileStorage{Path: dstfile} | ||
data, err := sess.LoadSession(context.Background()) | ||
if err != nil { | ||
t.Errorf("migratev120() = %v, want %v", err, nil) | ||
} | ||
if data == nil { | ||
t.Errorf("migratev120() = %v, want %v", data, "not nil") | ||
} | ||
sigSz := len(v1signature) | ||
if !bytes.Equal(data[:sigSz], []byte(v1signature)) { | ||
t.Errorf("migratev120() = %v, want %v", data[:sigSz], v1signature) | ||
} | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"Ver"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{"Version":1,"Data":{"Config":{"BlockedMode":false,"ForceTryIpv6":false,"Date":1536300799,"Expires":1536304334,"TestMode":false,"ThisDC":2,"DCOptions":[{"Flags":0,"Ipv6":false,"MediaOnly":false,"TCPObfuscatedOnly":false,"CDN":false,"Static":false,"ThisPortOnly":false,"ID":1,"IPAddress":"1.1.1.5","Port":443,"Secret":null},{"Flags":16,"Ipv6":false,"MediaOnly":false,"TCPObfuscatedOnly":false,"CDN":false,"Static":true,"ThisPortOnly":false,"ID":1,"IPAddress":"1.1.1.5","Port":443,"Secret":null},{"Flags":1,"Ipv6":true,"MediaOnly":false,"TCPObfuscatedOnly":false,"CDN":false,"Static":false,"ThisPortOnly":false,"ID":1,"IPAddress":"2001:0abc:defa:f000:0000:0000:0000:000a","Port":443,"Secret":null},{"Flags":0,"Ipv6":false,"MediaOnly":false,"TCPObfuscatedOnly":false,"CDN":false,"Static":false,"ThisPortOnly":false,"ID":2,"IPAddress":"1.1.1.4","Port":443,"Secret":null},{"Flags":16,"Ipv6":false,"MediaOnly":false,"TCPObfuscatedOnly":false,"CDN":false,"Static":true,"ThisPortOnly":false,"ID":2,"IPAddress":"1.1.1.4","Port":443,"Secret":null},{"Flags":2,"Ipv6":false,"MediaOnly":true,"TCPObfuscatedOnly":false,"CDN":false,"Static":false,"ThisPortOnly":false,"ID":2,"IPAddress":"1.1.1.2","Port":443,"Secret":null},{"Flags":1,"Ipv6":true,"MediaOnly":false,"TCPObfuscatedOnly":false,"CDN":false,"Static":false,"ThisPortOnly":false,"ID":2,"IPAddress":"2001:0abc:defa:f000:0000:0000:0000:000a","Port":443,"Secret":null},{"Flags":3,"Ipv6":true,"MediaOnly":true,"TCPObfuscatedOnly":false,"CDN":false,"Static":false,"ThisPortOnly":false,"ID":2,"IPAddress":"2001:0abc:def0:f002:0000:0000:0000:000b","Port":443,"Secret":null},{"Flags":0,"Ipv6":false,"MediaOnly":false,"TCPObfuscatedOnly":false,"CDN":false,"Static":false,"ThisPortOnly":false,"ID":3,"IPAddress":"1.1.1.1","Port":443,"Secret":null},{"Flags":16,"Ipv6":false,"MediaOnly":false,"TCPObfuscatedOnly":false,"CDN":false,"Static":true,"ThisPortOnly":false,"ID":3,"IPAddress":"1.1.1.1","Port":443,"Secret":null},{"Flags":1,"Ipv6":true,"MediaOnly":false,"TCPObfuscatedOnly":false,"CDN":false,"Static":false,"ThisPortOnly":false,"ID":3,"IPAddress":"2001:0abc:defd:f003:0000:0000:0000:000a","Port":443,"Secret":null},{"Flags":0,"Ipv6":false,"MediaOnly":false,"TCPObfuscatedOnly":false,"CDN":false,"Static":false,"ThisPortOnly":false,"ID":4,"IPAddress":"1.4.67.9","Port":443,"Secret":null},{"Flags":16,"Ipv6":false,"MediaOnly":false,"TCPObfuscatedOnly":false,"CDN":false,"Static":true,"ThisPortOnly":false,"ID":4,"IPAddress":"1.14.17.9","Port":443,"Secret":null},{"Flags":1,"Ipv6":true,"MediaOnly":false,"TCPObfuscatedOnly":false,"CDN":false,"Static":false,"ThisPortOnly":false,"ID":4,"IPAddress":"2001:0123:4567:f004:0000:0000:0000:000a","Port":443,"Secret":null},{"Flags":2,"Ipv6":false,"MediaOnly":true,"TCPObfuscatedOnly":false,"CDN":false,"Static":false,"ThisPortOnly":false,"ID":4,"IPAddress":"1.1.1.9","Port":443,"Secret":null},{"Flags":3,"Ipv6":true,"MediaOnly":true,"TCPObfuscatedOnly":false,"CDN":false,"Static":false,"ThisPortOnly":false,"ID":4,"IPAddress":"2001:0012:3456:f004:0000:0000:0000:000b","Port":443,"Secret":null},{"Flags":1,"Ipv6":true,"MediaOnly":false,"TCPObfuscatedOnly":false,"CDN":false,"Static":false,"ThisPortOnly":false,"ID":5,"IPAddress":"2001:0123:4567:f005:0000:0000:0000:000a","Port":443,"Secret":null},{"Flags":0,"Ipv6":false,"MediaOnly":false,"TCPObfuscatedOnly":false,"CDN":false,"Static":false,"ThisPortOnly":false,"ID":5,"IPAddress":"1.1.5.19","Port":443,"Secret":null},{"Flags":16,"Ipv6":false,"MediaOnly":false,"TCPObfuscatedOnly":false,"CDN":false,"Static":true,"ThisPortOnly":false,"ID":5,"IPAddress":"1.18.5.17","Port":443,"Secret":null}],"DCTxtDomainName":"abcd.efgh.com","TmpSessions":0,"WebfileDCID":4},"DC":2,"Addr":"","AuthKey":"UypugUhINJghExngTJ5L2fZ/ckBKey75DgpwWSiBROHVZad1UhGFyvmb7aQxO1g6W+8ERG44srIddnkQm8tl+vMtQO1jPtSv+scBCe3CsFpZFPa6Di3QtJ2AcuyY+w6nOMsEKAQK+kwP1dvta3wLcNHViivE/BBJzeUpwYVKG3/4nQuoJ1HnzK8FUq7E/adYx4w4DZGSlx7k33mC+Uazwz5liSn+vniM1qsz/xVwVUfSwe0FHK6+XmfoqIQ/C0Gvtc7TkRrdbYT0NsUIItw2Lza+zAhkwnKRZUIpHbF4hFJ6RnROKQJYew7DxCKos/RedUmYTTou5XabF7OcUZWAoQ==","AuthKeyID":"xNUXXKHzJvM=","Salt":123948397235972349}} |
Binary file not shown.