forked from Silverfish/proton-bridge
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 61e4ca5814 | |||
| 8e0693ab03 | |||
| a3d2df9d38 | |||
| f9f4ce996d | |||
| fc69b9aabb |
@ -48,7 +48,7 @@ lint:
|
|||||||
tags:
|
tags:
|
||||||
- medium
|
- medium
|
||||||
|
|
||||||
test:
|
test-linux:
|
||||||
stage: test
|
stage: test
|
||||||
only:
|
only:
|
||||||
- branches
|
- branches
|
||||||
@ -65,6 +65,14 @@ test:
|
|||||||
tags:
|
tags:
|
||||||
- medium
|
- medium
|
||||||
|
|
||||||
|
test-windows:
|
||||||
|
extends: .build-windows-base
|
||||||
|
stage: test
|
||||||
|
only:
|
||||||
|
- branches
|
||||||
|
script:
|
||||||
|
- make test
|
||||||
|
|
||||||
test-integration:
|
test-integration:
|
||||||
stage: test
|
stage: test
|
||||||
only:
|
only:
|
||||||
@ -96,6 +104,7 @@ build-qml:
|
|||||||
- cd internal/frontend/qml
|
- cd internal/frontend/qml
|
||||||
- tar -cvzf ../../../bridge_qml.tgz ./*
|
- tar -cvzf ../../../bridge_qml.tgz ./*
|
||||||
|
|
||||||
|
|
||||||
.build-base:
|
.build-base:
|
||||||
stage: build
|
stage: build
|
||||||
only:
|
only:
|
||||||
@ -134,6 +143,7 @@ build-linux-qa:
|
|||||||
paths:
|
paths:
|
||||||
- bridge_*.tgz
|
- bridge_*.tgz
|
||||||
|
|
||||||
|
|
||||||
.build-darwin-base:
|
.build-darwin-base:
|
||||||
extends: .build-base
|
extends: .build-base
|
||||||
before_script:
|
before_script:
|
||||||
@ -170,6 +180,40 @@ build-darwin-qa:
|
|||||||
paths:
|
paths:
|
||||||
- bridge_*.tgz
|
- bridge_*.tgz
|
||||||
|
|
||||||
|
|
||||||
|
.build-windows-base:
|
||||||
|
extends: .build-base
|
||||||
|
before_script:
|
||||||
|
- export GOROOT=/c/Go
|
||||||
|
- export PATH=$GOROOT/bin:$PATH
|
||||||
|
- export GOARCH=amd64
|
||||||
|
- export GOPATH=~/go
|
||||||
|
- export GO111MODULE=on
|
||||||
|
- export PATH=$GOPATH/bin:$PATH
|
||||||
|
- export MSYSTEM=
|
||||||
|
- export PATH=$PATH:/c/grrrQt/5.13.2/mingw73_64/bin
|
||||||
|
tags:
|
||||||
|
- windows-bridge
|
||||||
|
|
||||||
|
build-windows:
|
||||||
|
extends: .build-windows-base
|
||||||
|
artifacts:
|
||||||
|
name: "bridge-windows-$CI_COMMIT_SHORT_SHA"
|
||||||
|
paths:
|
||||||
|
- bridge_*.tgz
|
||||||
|
|
||||||
|
build-windows-qa:
|
||||||
|
extends: .build-windows-base
|
||||||
|
only:
|
||||||
|
- web
|
||||||
|
- branches
|
||||||
|
script:
|
||||||
|
- BUILD_TAGS="build_qa" make build
|
||||||
|
artifacts:
|
||||||
|
name: "bridge-windows-qa-$CI_COMMIT_SHORT_SHA"
|
||||||
|
paths:
|
||||||
|
- bridge_*.tgz
|
||||||
|
|
||||||
# Stage: MIRROR
|
# Stage: MIRROR
|
||||||
|
|
||||||
mirror-repo:
|
mirror-repo:
|
||||||
|
|||||||
11
Changelog.md
11
Changelog.md
@ -2,6 +2,17 @@
|
|||||||
|
|
||||||
Changelog [format](http://keepachangelog.com/en/1.0.0/)
|
Changelog [format](http://keepachangelog.com/en/1.0.0/)
|
||||||
|
|
||||||
|
## [Bridge 2.1.0] London
|
||||||
|
|
||||||
|
## Added
|
||||||
|
* GODT-1376: Add first userID to sentry scope.
|
||||||
|
* GODT-1375: Add host architecture to sentry reports.
|
||||||
|
* GODT-1364: Add windows CI machine for tests, and build.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
* GODT-1499: Remove message from DB once it is not on server any more.
|
||||||
|
|
||||||
|
|
||||||
## [Bridge 2.1.0] London
|
## [Bridge 2.1.0] London
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
2
Makefile
2
Makefile
@ -10,7 +10,7 @@ TARGET_OS?=${GOOS}
|
|||||||
.PHONY: build build-nogui build-launcher versioner hasher
|
.PHONY: build build-nogui build-launcher versioner hasher
|
||||||
|
|
||||||
# Keep version hardcoded so app build works also without Git repository.
|
# Keep version hardcoded so app build works also without Git repository.
|
||||||
BRIDGE_APP_VERSION?=2.1.0+git
|
BRIDGE_APP_VERSION?=2.1.1+git
|
||||||
APP_VERSION:=${BRIDGE_APP_VERSION}
|
APP_VERSION:=${BRIDGE_APP_VERSION}
|
||||||
SRC_ICO:=logo.ico
|
SRC_ICO:=logo.ico
|
||||||
SRC_ICNS:=Bridge.icns
|
SRC_ICNS:=Bridge.icns
|
||||||
|
|||||||
6
go.mod
6
go.mod
@ -28,6 +28,8 @@ require (
|
|||||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect
|
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect
|
||||||
github.com/cucumber/godog v0.12.1
|
github.com/cucumber/godog v0.12.1
|
||||||
github.com/cucumber/messages-go/v16 v16.0.1
|
github.com/cucumber/messages-go/v16 v16.0.1
|
||||||
|
github.com/elastic/go-sysinfo v1.7.1
|
||||||
|
github.com/elastic/go-windows v1.0.1 // indirect
|
||||||
github.com/emersion/go-imap-appendlimit v0.0.0-20190308131241-25671c986a6a
|
github.com/emersion/go-imap-appendlimit v0.0.0-20190308131241-25671c986a6a
|
||||||
github.com/emersion/go-imap-move v0.0.0-20190710073258-6e5a51a5b342
|
github.com/emersion/go-imap-move v0.0.0-20190710073258-6e5a51a5b342
|
||||||
github.com/emersion/go-imap-quota v0.0.0-20210203125329-619074823f3c
|
github.com/emersion/go-imap-quota v0.0.0-20210203125329-619074823f3c
|
||||||
@ -53,6 +55,7 @@ require (
|
|||||||
github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce
|
github.com/nsf/jsondiff v0.0.0-20200515183724-f29ed568f4ce
|
||||||
github.com/olekukonko/tablewriter v0.0.4 // indirect
|
github.com/olekukonko/tablewriter v0.0.4 // indirect
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
|
github.com/prometheus/procfs v0.7.3 // indirect
|
||||||
github.com/ricochet2200/go-disk-usage/du v0.0.0-20210707232629-ac9918953285
|
github.com/ricochet2200/go-disk-usage/du v0.0.0-20210707232629-ac9918953285
|
||||||
github.com/sirupsen/logrus v1.7.0
|
github.com/sirupsen/logrus v1.7.0
|
||||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
|
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
|
||||||
@ -64,8 +67,9 @@ require (
|
|||||||
github.com/vmihailenco/msgpack/v5 v5.1.3
|
github.com/vmihailenco/msgpack/v5 v5.1.3
|
||||||
go.etcd.io/bbolt v1.3.6
|
go.etcd.io/bbolt v1.3.6
|
||||||
golang.org/x/net v0.0.0-20211008194852-3b03d305991f
|
golang.org/x/net v0.0.0-20211008194852-3b03d305991f
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e
|
golang.org/x/sys v0.0.0-20220111092808-5a964db01320
|
||||||
golang.org/x/text v0.3.7
|
golang.org/x/text v0.3.7
|
||||||
|
howett.net/plist v1.0.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace (
|
replace (
|
||||||
|
|||||||
21
go.sum
21
go.sum
@ -113,6 +113,11 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUn
|
|||||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||||
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
|
||||||
|
github.com/elastic/go-sysinfo v1.7.1 h1:Wx4DSARcKLllpKT2TnFVdSUJOsybqMYCNQZq1/wO+s0=
|
||||||
|
github.com/elastic/go-sysinfo v1.7.1/go.mod h1:i1ZYdU10oLNfRzq4vq62BEwD2fH8KaWh6eh0ikPT9F0=
|
||||||
|
github.com/elastic/go-windows v1.0.0/go.mod h1:TsU0Nrp7/y3+VwE82FoZF8gC/XFg/Elz6CcloAxnPgU=
|
||||||
|
github.com/elastic/go-windows v1.0.1 h1:AlYZOldA+UJ0/2nBuqWdo90GFCgG9xuyw9SYzGUtJm0=
|
||||||
|
github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss=
|
||||||
github.com/emersion/go-imap-appendlimit v0.0.0-20190308131241-25671c986a6a h1:bMdSPm6sssuOFpIaveu3XGAijMS3Tq2S3EqFZmZxidc=
|
github.com/emersion/go-imap-appendlimit v0.0.0-20190308131241-25671c986a6a h1:bMdSPm6sssuOFpIaveu3XGAijMS3Tq2S3EqFZmZxidc=
|
||||||
github.com/emersion/go-imap-appendlimit v0.0.0-20190308131241-25671c986a6a/go.mod h1:ikgISoP7pRAolqsVP64yMteJa2FIpS6ju88eBT6K1yQ=
|
github.com/emersion/go-imap-appendlimit v0.0.0-20190308131241-25671c986a6a/go.mod h1:ikgISoP7pRAolqsVP64yMteJa2FIpS6ju88eBT6K1yQ=
|
||||||
github.com/emersion/go-imap-move v0.0.0-20190710073258-6e5a51a5b342 h1:5p1t3e1PomYgLWwEwhwEU5kVBwcyAcVrOpexv8AeZx0=
|
github.com/emersion/go-imap-move v0.0.0-20190710073258-6e5a51a5b342 h1:5p1t3e1PomYgLWwEwhwEU5kVBwcyAcVrOpexv8AeZx0=
|
||||||
@ -179,6 +184,7 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z
|
|||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
|
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
@ -241,6 +247,9 @@ github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0Gqw
|
|||||||
github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
|
github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
|
||||||
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7 h1:g0fAGBisHaEQ0TRq1iBvemFRf+8AEWEmBESSiWB3Vsc=
|
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7 h1:g0fAGBisHaEQ0TRq1iBvemFRf+8AEWEmBESSiWB3Vsc=
|
||||||
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
|
github.com/jaytaylor/html2text v0.0.0-20200412013138-3577fbdbcff7/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
|
||||||
|
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||||
|
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4=
|
||||||
|
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak=
|
||||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
@ -347,7 +356,10 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:
|
|||||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||||
|
github.com/prometheus/procfs v0.0.0-20190425082905-87a4384529e0/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||||
|
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
|
||||||
|
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
github.com/ricochet2200/go-disk-usage/du v0.0.0-20210707232629-ac9918953285 h1:d54EL9l+XteliUfUCGsEwwuk65dmmxX85VXF+9T6+50=
|
github.com/ricochet2200/go-disk-usage/du v0.0.0-20210707232629-ac9918953285 h1:d54EL9l+XteliUfUCGsEwwuk65dmmxX85VXF+9T6+50=
|
||||||
github.com/ricochet2200/go-disk-usage/du v0.0.0-20210707232629-ac9918953285/go.mod h1:fxIDly1xtudczrZeOOlfaUvd2OPb2qZAPuWdU2BsBTk=
|
github.com/ricochet2200/go-disk-usage/du v0.0.0-20210707232629-ac9918953285/go.mod h1:fxIDly1xtudczrZeOOlfaUvd2OPb2qZAPuWdU2BsBTk=
|
||||||
@ -509,6 +521,7 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
|
|||||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
|
||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
@ -532,11 +545,13 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20191025021431-6c3a3bfe00ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
@ -547,6 +562,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
||||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.0.0-20220111092808-5a964db01320 h1:0jf+tOCoZ3LyutmCOWpVni1chK4VfFLhRsDK7MhqGRY=
|
||||||
|
golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@ -622,6 +639,7 @@ gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
|||||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
|
gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
|
||||||
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
@ -635,4 +653,7 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
|
howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
|
||||||
|
howett.net/plist v1.0.0 h1:7CrbWYbPPO/PyNy38b2EB/+gYbjCe2DXBxgtOOZbSQM=
|
||||||
|
howett.net/plist v1.0.0/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
|
|||||||
@ -189,6 +189,8 @@ func New( // nolint[funlen]
|
|||||||
|
|
||||||
cm := pmapi.New(cfg)
|
cm := pmapi.New(cfg)
|
||||||
|
|
||||||
|
sentryReporter.SetClientFromManager(cm)
|
||||||
|
|
||||||
cm.AddConnectionObserver(pmapi.NewConnectionObserver(
|
cm.AddConnectionObserver(pmapi.NewConnectionObserver(
|
||||||
func() { listener.Emit(events.InternetOffEvent, "") },
|
func() { listener.Emit(events.InternetOffEvent, "") },
|
||||||
func() { listener.Emit(events.InternetOnEvent, "") },
|
func() { listener.Emit(events.InternetOnEvent, "") },
|
||||||
|
|||||||
@ -25,81 +25,118 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
const testPrefFilePath = "/tmp/pref.json"
|
|
||||||
|
|
||||||
func TestLoadNoKeyValueStore(t *testing.T) {
|
func TestLoadNoKeyValueStore(t *testing.T) {
|
||||||
pref := newTestEmptyKeyValueStore(t)
|
r := require.New(t)
|
||||||
require.Equal(t, "", pref.Get("key"))
|
pref, clean := newTestEmptyKeyValueStore(r)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
|
r.Equal("", pref.Get("key"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLoadBadKeyValueStore(t *testing.T) {
|
func TestLoadBadKeyValueStore(t *testing.T) {
|
||||||
require.NoError(t, ioutil.WriteFile(testPrefFilePath, []byte("{\"key\":\"value"), 0700))
|
r := require.New(t)
|
||||||
pref := newKeyValueStore(testPrefFilePath)
|
path, clean := newTmpFile(r)
|
||||||
require.Equal(t, "", pref.Get("key"))
|
defer clean()
|
||||||
|
|
||||||
|
r.NoError(ioutil.WriteFile(path, []byte("{\"key\":\"MISSING_QUOTES"), 0700))
|
||||||
|
pref := newKeyValueStore(path)
|
||||||
|
r.Equal("", pref.Get("key"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestKeyValueStoreGet(t *testing.T) {
|
func TestKeyValueStor(t *testing.T) {
|
||||||
pref := newTestKeyValueStore(t)
|
r := require.New(t)
|
||||||
require.Equal(t, "value", pref.Get("str"))
|
pref, clean := newTestKeyValueStore(r)
|
||||||
require.Equal(t, "42", pref.Get("int"))
|
defer clean()
|
||||||
require.Equal(t, "true", pref.Get("bool"))
|
|
||||||
require.Equal(t, "t", pref.Get("falseBool"))
|
r.Equal("value", pref.Get("str"))
|
||||||
|
r.Equal("42", pref.Get("int"))
|
||||||
|
r.Equal("true", pref.Get("bool"))
|
||||||
|
r.Equal("t", pref.Get("falseBool"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestKeyValueStoreGetInt(t *testing.T) {
|
func TestKeyValueStoreGetInt(t *testing.T) {
|
||||||
pref := newTestKeyValueStore(t)
|
r := require.New(t)
|
||||||
require.Equal(t, 0, pref.GetInt("str"))
|
pref, clean := newTestKeyValueStore(r)
|
||||||
require.Equal(t, 42, pref.GetInt("int"))
|
defer clean()
|
||||||
require.Equal(t, 0, pref.GetInt("bool"))
|
|
||||||
require.Equal(t, 0, pref.GetInt("falseBool"))
|
r.Equal(0, pref.GetInt("str"))
|
||||||
|
r.Equal(42, pref.GetInt("int"))
|
||||||
|
r.Equal(0, pref.GetInt("bool"))
|
||||||
|
r.Equal(0, pref.GetInt("falseBool"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestKeyValueStoreGetBool(t *testing.T) {
|
func TestKeyValueStoreGetBool(t *testing.T) {
|
||||||
pref := newTestKeyValueStore(t)
|
r := require.New(t)
|
||||||
require.Equal(t, false, pref.GetBool("str"))
|
pref, clean := newTestKeyValueStore(r)
|
||||||
require.Equal(t, false, pref.GetBool("int"))
|
defer clean()
|
||||||
require.Equal(t, true, pref.GetBool("bool"))
|
|
||||||
require.Equal(t, false, pref.GetBool("falseBool"))
|
r.Equal(false, pref.GetBool("str"))
|
||||||
|
r.Equal(false, pref.GetBool("int"))
|
||||||
|
r.Equal(true, pref.GetBool("bool"))
|
||||||
|
r.Equal(false, pref.GetBool("falseBool"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestKeyValueStoreSetDefault(t *testing.T) {
|
func TestKeyValueStoreSetDefault(t *testing.T) {
|
||||||
pref := newTestEmptyKeyValueStore(t)
|
r := require.New(t)
|
||||||
|
pref, clean := newTestEmptyKeyValueStore(r)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
pref.setDefault("key", "value")
|
pref.setDefault("key", "value")
|
||||||
pref.setDefault("key", "othervalue")
|
pref.setDefault("key", "othervalue")
|
||||||
require.Equal(t, "value", pref.Get("key"))
|
r.Equal("value", pref.Get("key"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestKeyValueStoreSet(t *testing.T) {
|
func TestKeyValueStoreSet(t *testing.T) {
|
||||||
pref := newTestEmptyKeyValueStore(t)
|
r := require.New(t)
|
||||||
|
pref, clean := newTestEmptyKeyValueStore(r)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
pref.Set("str", "value")
|
pref.Set("str", "value")
|
||||||
checkSavedKeyValueStore(t, "{\n\t\"str\": \"value\"\n}")
|
checkSavedKeyValueStore(r, pref.path, "{\n\t\"str\": \"value\"\n}")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestKeyValueStoreSetInt(t *testing.T) {
|
func TestKeyValueStoreSetInt(t *testing.T) {
|
||||||
pref := newTestEmptyKeyValueStore(t)
|
r := require.New(t)
|
||||||
|
pref, clean := newTestEmptyKeyValueStore(r)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
pref.SetInt("int", 42)
|
pref.SetInt("int", 42)
|
||||||
checkSavedKeyValueStore(t, "{\n\t\"int\": \"42\"\n}")
|
checkSavedKeyValueStore(r, pref.path, "{\n\t\"int\": \"42\"\n}")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestKeyValueStoreSetBool(t *testing.T) {
|
func TestKeyValueStoreSetBool(t *testing.T) {
|
||||||
pref := newTestEmptyKeyValueStore(t)
|
r := require.New(t)
|
||||||
|
pref, clean := newTestEmptyKeyValueStore(r)
|
||||||
|
defer clean()
|
||||||
|
|
||||||
pref.SetBool("trueBool", true)
|
pref.SetBool("trueBool", true)
|
||||||
pref.SetBool("falseBool", false)
|
pref.SetBool("falseBool", false)
|
||||||
checkSavedKeyValueStore(t, "{\n\t\"falseBool\": \"false\",\n\t\"trueBool\": \"true\"\n}")
|
checkSavedKeyValueStore(r, pref.path, "{\n\t\"falseBool\": \"false\",\n\t\"trueBool\": \"true\"\n}")
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestEmptyKeyValueStore(t *testing.T) *keyValueStore {
|
func newTmpFile(r *require.Assertions) (path string, clean func()) {
|
||||||
require.NoError(t, os.RemoveAll(testPrefFilePath))
|
tmpfile, err := ioutil.TempFile("", "pref.*.json")
|
||||||
return newKeyValueStore(testPrefFilePath)
|
r.NoError(err)
|
||||||
|
defer r.NoError(tmpfile.Close())
|
||||||
|
|
||||||
|
return tmpfile.Name(), func() {
|
||||||
|
r.NoError(os.Remove(tmpfile.Name()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestKeyValueStore(t *testing.T) *keyValueStore {
|
func newTestEmptyKeyValueStore(r *require.Assertions) (*keyValueStore, func()) {
|
||||||
require.NoError(t, ioutil.WriteFile(testPrefFilePath, []byte("{\"str\":\"value\",\"int\":\"42\",\"bool\":\"true\",\"falseBool\":\"t\"}"), 0700))
|
path, clean := newTmpFile(r)
|
||||||
return newKeyValueStore(testPrefFilePath)
|
return newKeyValueStore(path), clean
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkSavedKeyValueStore(t *testing.T, expected string) {
|
func newTestKeyValueStore(r *require.Assertions) (*keyValueStore, func()) {
|
||||||
data, err := ioutil.ReadFile(testPrefFilePath)
|
path, clean := newTmpFile(r)
|
||||||
require.NoError(t, err)
|
r.NoError(ioutil.WriteFile(path, []byte("{\"str\":\"value\",\"int\":\"42\",\"bool\":\"true\",\"falseBool\":\"t\"}"), 0700))
|
||||||
require.Equal(t, expected, string(data))
|
return newKeyValueStore(path), clean
|
||||||
|
}
|
||||||
|
|
||||||
|
func checkSavedKeyValueStore(r *require.Assertions, path, expected string) {
|
||||||
|
data, err := ioutil.ReadFile(path)
|
||||||
|
r.NoError(err)
|
||||||
|
r.Equal(expected, string(data))
|
||||||
}
|
}
|
||||||
|
|||||||
49
internal/sentry/hostarch_darwin.go
Normal file
49
internal/sentry/hostarch_darwin.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright (c) 2022 Proton Technologies AG
|
||||||
|
//
|
||||||
|
// This file is part of ProtonMail Bridge.
|
||||||
|
//
|
||||||
|
// ProtonMail Bridge is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// ProtonMail Bridge is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//go:build darwin
|
||||||
|
// +build darwin
|
||||||
|
|
||||||
|
package sentry
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/elastic/go-sysinfo"
|
||||||
|
"golang.org/x/sys/unix"
|
||||||
|
)
|
||||||
|
|
||||||
|
const translatedProcDarwin = "sysctl.proc_translated"
|
||||||
|
|
||||||
|
func getHostAarch() string {
|
||||||
|
host, err := sysinfo.Host()
|
||||||
|
if err != nil {
|
||||||
|
return "not-detected"
|
||||||
|
}
|
||||||
|
|
||||||
|
// It is not possible to retrieve real hardware architecture once using
|
||||||
|
// rosetta. But it is possible to detect the process translation if
|
||||||
|
// rosetta is used.
|
||||||
|
res, err := unix.SysctlRaw(translatedProcDarwin)
|
||||||
|
if err != nil || len(res) > 4 {
|
||||||
|
return host.Info().Architecture + "_err"
|
||||||
|
}
|
||||||
|
|
||||||
|
if res[0] == 1 {
|
||||||
|
return host.Info().Architecture + "_rosetta"
|
||||||
|
}
|
||||||
|
|
||||||
|
return host.Info().Architecture
|
||||||
|
}
|
||||||
31
internal/sentry/hostarch_default.go
Normal file
31
internal/sentry/hostarch_default.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// Copyright (c) 2022 Proton Technologies AG
|
||||||
|
//
|
||||||
|
// This file is part of ProtonMail Bridge.
|
||||||
|
//
|
||||||
|
// ProtonMail Bridge is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// ProtonMail Bridge is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//go:build !darwin
|
||||||
|
// +build !darwin
|
||||||
|
|
||||||
|
package sentry
|
||||||
|
|
||||||
|
import "github.com/elastic/go-sysinfo"
|
||||||
|
|
||||||
|
func getHostAarch() string {
|
||||||
|
host, err := sysinfo.Host()
|
||||||
|
if err != nil {
|
||||||
|
return "not-detected"
|
||||||
|
}
|
||||||
|
return host.Info().Architecture
|
||||||
|
}
|
||||||
@ -20,18 +20,20 @@ package sentry
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ProtonMail/proton-bridge/internal/constants"
|
"github.com/ProtonMail/proton-bridge/internal/constants"
|
||||||
|
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||||
"github.com/getsentry/sentry-go"
|
"github.com/getsentry/sentry-go"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var skippedFunctions = []string{} //nolint[gochecknoglobals]
|
var skippedFunctions = []string{} //nolint[gochecknoglobals]
|
||||||
|
|
||||||
func init() { // nolint[noinit]
|
func init() { //nolint[noinit, gochecknoinits]
|
||||||
if err := sentry.Init(sentry.ClientOptions{
|
if err := sentry.Init(sentry.ClientOptions{
|
||||||
Dsn: constants.DSNSentry,
|
Dsn: constants.DSNSentry,
|
||||||
Release: constants.Revision,
|
Release: constants.Revision,
|
||||||
@ -42,13 +44,20 @@ func init() { // nolint[noinit]
|
|||||||
|
|
||||||
sentry.ConfigureScope(func(scope *sentry.Scope) {
|
sentry.ConfigureScope(func(scope *sentry.Scope) {
|
||||||
scope.SetFingerprint([]string{"{{ default }}"})
|
scope.SetFingerprint([]string{"{{ default }}"})
|
||||||
|
scope.SetTag("UserID", "not-defined")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
sentry.Logger = log.New(
|
||||||
|
logrus.WithField("pkg", "sentry-go").WriterLevel(logrus.WarnLevel),
|
||||||
|
"", 0,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Reporter struct {
|
type Reporter struct {
|
||||||
appName string
|
appName string
|
||||||
appVersion string
|
appVersion string
|
||||||
userAgent fmt.Stringer
|
userAgent fmt.Stringer
|
||||||
|
hostArch string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewReporter creates new sentry reporter with appName and appVersion to report.
|
// NewReporter creates new sentry reporter with appName and appVersion to report.
|
||||||
@ -57,6 +66,7 @@ func NewReporter(appName, appVersion string, userAgent fmt.Stringer) *Reporter {
|
|||||||
appName: appName,
|
appName: appName,
|
||||||
appVersion: appVersion,
|
appVersion: appVersion,
|
||||||
userAgent: userAgent,
|
userAgent: userAgent,
|
||||||
|
hostArch: getHostAarch(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +119,7 @@ func (r *Reporter) scopedReport(context map[string]interface{}, doReport func())
|
|||||||
"Client": r.appName,
|
"Client": r.appName,
|
||||||
"Version": r.appVersion,
|
"Version": r.appVersion,
|
||||||
"UserAgent": r.userAgent.String(),
|
"UserAgent": r.userAgent.String(),
|
||||||
"UserID": "",
|
"HostArch": r.hostArch,
|
||||||
}
|
}
|
||||||
|
|
||||||
sentry.WithScope(func(scope *sentry.Scope) {
|
sentry.WithScope(func(scope *sentry.Scope) {
|
||||||
@ -179,3 +189,6 @@ func isFunctionFilteredOut(function string) bool {
|
|||||||
func Flush(maxWaiTime time.Duration) {
|
func Flush(maxWaiTime time.Duration) {
|
||||||
sentry.Flush(maxWaiTime)
|
sentry.Flush(maxWaiTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Reporter) SetClientFromManager(cm pmapi.Manager) {
|
||||||
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import (
|
|||||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||||
"github.com/ProtonMail/proton-bridge/internal/store/cache"
|
"github.com/ProtonMail/proton-bridge/internal/store/cache"
|
||||||
"github.com/ProtonMail/proton-bridge/pkg/message"
|
"github.com/ProtonMail/proton-bridge/pkg/message"
|
||||||
|
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||||
bolt "go.etcd.io/bbolt"
|
bolt "go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -126,6 +127,7 @@ func (store *Store) getCachedMessage(messageID string) ([]byte, error) {
|
|||||||
|
|
||||||
literal, err := job.GetResult()
|
literal, err := job.GetResult()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
store.checkAndRemoveDeletedMessage(err, messageID)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,8 +186,21 @@ func (store *Store) BuildAndCacheMessage(ctx context.Context, messageID string)
|
|||||||
|
|
||||||
literal, err := job.GetResult()
|
literal, err := job.GetResult()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
store.checkAndRemoveDeletedMessage(err, messageID)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return store.cache.Set(store.user.ID(), messageID, literal)
|
return store.cache.Set(store.user.ID(), messageID, literal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (store *Store) checkAndRemoveDeletedMessage(err error, msgID string) {
|
||||||
|
if _, ok := err.(pmapi.ErrUnprocessableEntity); !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
l := store.log.WithError(err).WithField("msgID", msgID)
|
||||||
|
l.Warn("Deleting message which was not found on API")
|
||||||
|
|
||||||
|
if deleteErr := store.deleteMessageEvent(msgID); deleteErr != nil {
|
||||||
|
l.WithField("deleteErr", deleteErr).Error("Failed to delete non-existed API message from DB")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
8
internal/store/cache/disk.go
vendored
8
internal/store/cache/disk.go
vendored
@ -63,10 +63,16 @@ func NewOnDiskCache(path string, cmp Compressor, opts Options) (Cache, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
file, err := ioutil.TempFile(path, "tmp")
|
file, err := ioutil.TempFile(path, "tmp")
|
||||||
|
defer func() {
|
||||||
|
file.Close() //nolint[errcheck]
|
||||||
|
os.Remove(file.Name()) //nolint[errcheck]
|
||||||
|
}()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot open test write target: %w", err)
|
||||||
|
}
|
||||||
|
if _, err := file.Write([]byte("test-write")); err != nil {
|
||||||
return nil, fmt.Errorf("cannot write to target: %w", err)
|
return nil, fmt.Errorf("cannot write to target: %w", err)
|
||||||
}
|
}
|
||||||
os.Remove(file.Name()) //nolint[errcheck]
|
|
||||||
|
|
||||||
usage := du.NewDiskUsage(path)
|
usage := du.NewDiskUsage(path)
|
||||||
|
|
||||||
|
|||||||
@ -229,7 +229,10 @@ func (u *Users) MigrateCache(srcPath, dstPath string) error {
|
|||||||
// (read-only is conserved). Do copy instead.
|
// (read-only is conserved). Do copy instead.
|
||||||
tmp, err := ioutil.TempFile(srcPath, "tmp")
|
tmp, err := ioutil.TempFile(srcPath, "tmp")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
defer os.Remove(tmp.Name()) //nolint[errcheck]
|
defer func() {
|
||||||
|
tmp.Close() //nolint[errcheck]
|
||||||
|
os.Remove(tmp.Name()) //nolint[errcheck]
|
||||||
|
}()
|
||||||
|
|
||||||
if err := os.Rename(srcPath, dstPath); err == nil {
|
if err := os.Rename(srcPath, dstPath); err == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@ -175,6 +175,7 @@ func initMocks(t *testing.T) mocks {
|
|||||||
|
|
||||||
cacheFile, err := ioutil.TempFile("", "bridge-store-cache-*.db")
|
cacheFile, err := ioutil.TempFile("", "bridge-store-cache-*.db")
|
||||||
r.NoError(t, err, "could not get temporary file for store cache")
|
r.NoError(t, err, "could not get temporary file for store cache")
|
||||||
|
r.NoError(t, cacheFile.Close())
|
||||||
|
|
||||||
m := mocks{
|
m := mocks{
|
||||||
t: t,
|
t: t,
|
||||||
@ -201,6 +202,7 @@ func initMocks(t *testing.T) mocks {
|
|||||||
|
|
||||||
dbFile, err := ioutil.TempFile(t.TempDir(), "bridge-store-db-*.db")
|
dbFile, err := ioutil.TempFile(t.TempDir(), "bridge-store-db-*.db")
|
||||||
r.NoError(t, err, "could not get temporary file for store db")
|
r.NoError(t, err, "could not get temporary file for store db")
|
||||||
|
r.NoError(t, dbFile.Close())
|
||||||
|
|
||||||
return store.New(
|
return store.New(
|
||||||
sentryReporter,
|
sentryReporter,
|
||||||
|
|||||||
@ -32,7 +32,7 @@ import (
|
|||||||
// RemoveOldVersions is a noop on darwin; we don't test it there.
|
// RemoveOldVersions is a noop on darwin; we don't test it there.
|
||||||
|
|
||||||
func TestRemoveOldVersions(t *testing.T) {
|
func TestRemoveOldVersions(t *testing.T) {
|
||||||
updates, err := ioutil.TempDir("", "updates")
|
updates, err := ioutil.TempDir(t.TempDir(), "updates")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
v := newTestVersioner(t, "myCoolApp", updates, "2.3.4-beta", "2.3.4", "2.3.5", "2.4.0")
|
v := newTestVersioner(t, "myCoolApp", updates, "2.3.4-beta", "2.3.4", "2.3.5", "2.4.0")
|
||||||
|
|||||||
@ -65,11 +65,13 @@ func makeDummyVersionDirectory(t *testing.T, exeName, updates, version string) s
|
|||||||
exe, err := os.Create(filepath.Join(target, getExeName(exeName)))
|
exe, err := os.Create(filepath.Join(target, getExeName(exeName)))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, exe)
|
require.NotNil(t, exe)
|
||||||
|
require.NoError(t, exe.Close())
|
||||||
require.NoError(t, os.Chmod(exe.Name(), 0700))
|
require.NoError(t, os.Chmod(exe.Name(), 0700))
|
||||||
|
|
||||||
sig, err := os.Create(filepath.Join(target, getExeName(exeName)+".sig"))
|
sig, err := os.Create(filepath.Join(target, getExeName(exeName)+".sig"))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, sig)
|
require.NotNil(t, sig)
|
||||||
|
require.NoError(t, sig.Close())
|
||||||
|
|
||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -33,6 +34,7 @@ var (
|
|||||||
wantOutput = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
wantOutput = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
|
||||||
testProcessSleep = 100 // ms
|
testProcessSleep = 100 // ms
|
||||||
runParallelTimeOverhead = 150 // ms
|
runParallelTimeOverhead = 150 // ms
|
||||||
|
windowsCIExtra = 250 // ms - estimated experimentally
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestParallel(t *testing.T) {
|
func TestParallel(t *testing.T) {
|
||||||
@ -56,6 +58,9 @@ func TestParallel(t *testing.T) {
|
|||||||
|
|
||||||
wantMinDuration := int(math.Ceil(float64(len(testInput))/float64(workers))) * testProcessSleep
|
wantMinDuration := int(math.Ceil(float64(len(testInput))/float64(workers))) * testProcessSleep
|
||||||
wantMaxDuration := wantMinDuration + runParallelTimeOverhead
|
wantMaxDuration := wantMinDuration + runParallelTimeOverhead
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
wantMaxDuration += windowsCIExtra
|
||||||
|
}
|
||||||
r.True(t, duration.Nanoseconds() > int64(wantMinDuration*1000000), "Duration too short: %v (expected: %v)", duration, wantMinDuration)
|
r.True(t, duration.Nanoseconds() > int64(wantMinDuration*1000000), "Duration too short: %v (expected: %v)", duration, wantMinDuration)
|
||||||
r.True(t, duration.Nanoseconds() < int64(wantMaxDuration*1000000), "Duration too long: %v (expected: %v)", duration, wantMaxDuration)
|
r.True(t, duration.Nanoseconds() < int64(wantMaxDuration*1000000), "Duration too long: %v (expected: %v)", duration, wantMaxDuration)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -82,4 +82,5 @@ type AuthRefreshHandler func(*AuthRefresh)
|
|||||||
type clientManager interface {
|
type clientManager interface {
|
||||||
r(context.Context) *resty.Request
|
r(context.Context) *resty.Request
|
||||||
authRefresh(context.Context, string, string) (*AuthRefresh, error)
|
authRefresh(context.Context, string, string) (*AuthRefresh, error)
|
||||||
|
setSentryUserID(userID string)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,9 +32,9 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ErrUnprocessableEntity struct {
|
type ErrUnprocessableEntity struct {
|
||||||
originalError error
|
OriginalError error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (err ErrUnprocessableEntity) Error() string {
|
func (err ErrUnprocessableEntity) Error() string {
|
||||||
return err.originalError.Error()
|
return err.OriginalError.Error()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/getsentry/sentry-go"
|
||||||
"github.com/go-resty/resty/v2"
|
"github.com/go-resty/resty/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -37,6 +38,7 @@ type manager struct {
|
|||||||
|
|
||||||
pingMutex *sync.RWMutex
|
pingMutex *sync.RWMutex
|
||||||
isPinging bool
|
isPinging bool
|
||||||
|
setSentryUserIDOnce sync.Once
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(cfg Config) Manager {
|
func New(cfg Config) Manager {
|
||||||
@ -50,6 +52,7 @@ func newManager(cfg Config) *manager {
|
|||||||
locker: &sync.Mutex{},
|
locker: &sync.Mutex{},
|
||||||
pingMutex: &sync.RWMutex{},
|
pingMutex: &sync.RWMutex{},
|
||||||
isPinging: false,
|
isPinging: false,
|
||||||
|
setSentryUserIDOnce: sync.Once{},
|
||||||
}
|
}
|
||||||
|
|
||||||
proxyDialer, transport := newProxyDialerAndTransport(cfg)
|
proxyDialer, transport := newProxyDialerAndTransport(cfg)
|
||||||
@ -158,3 +161,11 @@ func (m *manager) handleRequestFailure(req *resty.Request, err error) {
|
|||||||
|
|
||||||
go m.pingUntilSuccess()
|
go m.pingUntilSuccess()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *manager) setSentryUserID(userID string) {
|
||||||
|
m.setSentryUserIDOnce.Do(func() {
|
||||||
|
sentry.ConfigureScope(func(scope *sentry.Scope) {
|
||||||
|
scope.SetTag("UserID", userID)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@ -21,7 +21,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||||
"github.com/getsentry/sentry-go"
|
|
||||||
"github.com/go-resty/resty/v2"
|
"github.com/go-resty/resty/v2"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
@ -126,7 +125,7 @@ func (c *client) UpdateUser(ctx context.Context) (*User, error) {
|
|||||||
|
|
||||||
c.user = user
|
c.user = user
|
||||||
c.addresses = addresses
|
c.addresses = addresses
|
||||||
sentry.ConfigureScope(func(scope *sentry.Scope) { scope.SetUser(sentry.User{ID: user.ID}) })
|
c.manager.setSentryUserID(user.ID)
|
||||||
|
|
||||||
return user, err
|
return user, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
.PHONY: check-go check-godog install-godog test test-bridge test-live test-live-bridge test-stage test-debug test-live-debug bench
|
.PHONY: check-go check-godog install-godog test test-bridge test-live test-live-bridge test-stage test-debug test-live-debug bench
|
||||||
|
|
||||||
export GO111MODULE=on
|
export GO111MODULE=on
|
||||||
export BRIDGE_VERSION:=2.1.0+integrationtests
|
export BRIDGE_VERSION:=2.1.1+integrationtests
|
||||||
export VERBOSITY?=fatal
|
export VERBOSITY?=fatal
|
||||||
export TEST_DATA=testdata
|
export TEST_DATA=testdata
|
||||||
|
|
||||||
|
|||||||
@ -45,6 +45,7 @@ type PMAPIController interface {
|
|||||||
GetCalls(method, path string) [][]byte
|
GetCalls(method, path string) [][]byte
|
||||||
LockEvents(username string)
|
LockEvents(username string)
|
||||||
UnlockEvents(username string)
|
UnlockEvents(username string)
|
||||||
|
RemoveUserMessageWithoutEvent(username, messageID string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPMAPIController(listener listener.Listener) (PMAPIController, pmapi.Manager) {
|
func newPMAPIController(listener listener.Listener) (PMAPIController, pmapi.Manager) {
|
||||||
|
|||||||
@ -234,3 +234,19 @@ func (ctl *Controller) LockEvents(string) {}
|
|||||||
|
|
||||||
// UnlockEvents doesn't needs to be implemented for fakeAPI.
|
// UnlockEvents doesn't needs to be implemented for fakeAPI.
|
||||||
func (ctl *Controller) UnlockEvents(string) {}
|
func (ctl *Controller) UnlockEvents(string) {}
|
||||||
|
|
||||||
|
func (ctl *Controller) RemoveUserMessageWithoutEvent(username string, messageID string) error {
|
||||||
|
msgs, ok := ctl.messagesByUsername[username]
|
||||||
|
if !ok {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, message := range msgs {
|
||||||
|
if message.ID == messageID {
|
||||||
|
ctl.messagesByUsername[username] = append(msgs[:i], msgs[i+1:]...)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors.New("message not found")
|
||||||
|
}
|
||||||
|
|||||||
@ -37,7 +37,7 @@ func (api *FakePMAPI) GetMessage(_ context.Context, apiID string) (*pmapi.Messag
|
|||||||
if msg := api.getMessage(apiID); msg != nil {
|
if msg := api.getMessage(apiID); msg != nil {
|
||||||
return msg, nil
|
return msg, nil
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("message %s not found", apiID)
|
return nil, pmapi.ErrUnprocessableEntity{OriginalError: fmt.Errorf("message %s not found", apiID)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListMessages does not implement following filters:
|
// ListMessages does not implement following filters:
|
||||||
|
|||||||
@ -177,3 +177,14 @@ Feature: IMAP fetch messages
|
|||||||
# We had bug to incorectly set empty date, so let's make sure
|
# We had bug to incorectly set empty date, so let's make sure
|
||||||
# there is no reference anywhere in the response.
|
# there is no reference anywhere in the response.
|
||||||
And IMAP response does not contain "\nDate: Thu, 01 Jan 1970"
|
And IMAP response does not contain "\nDate: Thu, 01 Jan 1970"
|
||||||
|
|
||||||
|
Scenario: Fetch of message which was deleted without event processed
|
||||||
|
Given there are 10 messages in mailbox "INBOX" for "user"
|
||||||
|
And message "5" was deleted forever without event processed for "user"
|
||||||
|
And there is IMAP client logged in as "user"
|
||||||
|
And there is IMAP client selected in "INBOX"
|
||||||
|
When IMAP client fetches bodies "1:*"
|
||||||
|
Then IMAP response is "NO"
|
||||||
|
When IMAP client fetches bodies "1:*"
|
||||||
|
Then IMAP response is "OK"
|
||||||
|
And IMAP response has 9 messages
|
||||||
|
|||||||
@ -104,3 +104,14 @@ func (ctl *Controller) GetMessages(username, labelID string) ([]*pmapi.Message,
|
|||||||
|
|
||||||
return messages, nil
|
return messages, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ctl *Controller) RemoveUserMessageWithoutEvent(username string, messageID string) error {
|
||||||
|
client, err := getPersistentClient(username)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
addMessageIDToSkipEventOnceDeleted(messageID)
|
||||||
|
|
||||||
|
return client.DeleteMessages(context.Background(), []string{messageID})
|
||||||
|
}
|
||||||
|
|||||||
@ -49,6 +49,7 @@ var persistentClients = struct {
|
|||||||
saltByName map[string]string
|
saltByName map[string]string
|
||||||
|
|
||||||
eventsPaused sync.WaitGroup
|
eventsPaused sync.WaitGroup
|
||||||
|
skipDeletedMessageID map[string]struct{}
|
||||||
}{}
|
}{}
|
||||||
|
|
||||||
type persistentClient struct {
|
type persistentClient struct {
|
||||||
@ -79,7 +80,40 @@ func (pc *persistentClient) GetEvent(ctx context.Context, eventID string) (*pmap
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("cannot convert to normal client")
|
return nil, errors.New("cannot convert to normal client")
|
||||||
}
|
}
|
||||||
return normalClient.GetEvent(ctx, eventID)
|
|
||||||
|
event, err := normalClient.GetEvent(ctx, eventID)
|
||||||
|
if err != nil {
|
||||||
|
return event, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return skipDeletedMessageIDs(event), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func addMessageIDToSkipEventOnceDeleted(msgID string) {
|
||||||
|
if persistentClients.skipDeletedMessageID == nil {
|
||||||
|
persistentClients.skipDeletedMessageID = map[string]struct{}{}
|
||||||
|
}
|
||||||
|
persistentClients.skipDeletedMessageID[msgID] = struct{}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func skipDeletedMessageIDs(event *pmapi.Event) *pmapi.Event {
|
||||||
|
if len(event.Messages) == 0 {
|
||||||
|
return event
|
||||||
|
}
|
||||||
|
|
||||||
|
n := 0
|
||||||
|
for i, m := range event.Messages {
|
||||||
|
if _, ok := persistentClients.skipDeletedMessageID[m.ID]; ok && m.Action == pmapi.EventDelete {
|
||||||
|
delete(persistentClients.skipDeletedMessageID, m.ID)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
event.Messages[i] = m
|
||||||
|
n++
|
||||||
|
}
|
||||||
|
event.Messages = event.Messages[:n]
|
||||||
|
|
||||||
|
return event
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetupPersistentClients() {
|
func SetupPersistentClients() {
|
||||||
|
|||||||
@ -38,6 +38,7 @@ func StoreSetupFeatureContext(s *godog.ScenarioContext) {
|
|||||||
s.Step(`^there are messages for "([^"]*)" as follows$`, thereAreSomeMessagesForUserAsFollows)
|
s.Step(`^there are messages for "([^"]*)" as follows$`, thereAreSomeMessagesForUserAsFollows)
|
||||||
s.Step(`^there are (\d+) messages in mailbox(?:es)? "([^"]*)" for address "([^"]*)" of "([^"]*)"$`, thereAreSomeMessagesInMailboxesForAddressOfUser)
|
s.Step(`^there are (\d+) messages in mailbox(?:es)? "([^"]*)" for address "([^"]*)" of "([^"]*)"$`, thereAreSomeMessagesInMailboxesForAddressOfUser)
|
||||||
s.Step(`^wait for Sphinx to create duplication indices$`, waitForSphinx)
|
s.Step(`^wait for Sphinx to create duplication indices$`, waitForSphinx)
|
||||||
|
s.Step(`^message(?:s)? "([^"]*)" (?:was|were) deleted forever without event processed for "([^"]*)"$`, messageWasDeletedWithoutEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
func thereIsUserWithMailboxes(bddUserID string, mailboxes *godog.Table) error {
|
func thereIsUserWithMailboxes(bddUserID string, mailboxes *godog.Table) error {
|
||||||
@ -319,3 +320,16 @@ func waitForSphinx() error {
|
|||||||
time.Sleep(15 * time.Second)
|
time.Sleep(15 * time.Second)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func messageWasDeletedWithoutEvent(bddMessageID, bddUserID string) error {
|
||||||
|
account := ctx.GetTestAccount(bddUserID)
|
||||||
|
if account == nil {
|
||||||
|
return godog.ErrPending
|
||||||
|
}
|
||||||
|
apiID, err := ctx.GetAPIMessageID(account.Username(), bddMessageID)
|
||||||
|
if err != nil {
|
||||||
|
return internalError(err, "getting BDD message ID %s", bddMessageID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx.GetPMAPIController().RemoveUserMessageWithoutEvent(account.Username(), apiID)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user