• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pomerium / pomerium / 19969861017

05 Dec 2025 04:52PM UTC coverage: 52.99% (+0.2%) from 52.751%
19969861017

push

github

web-flow
feat(ssh/UI) SSH session binding UI improvements (#5963)

## Summary

<!--  For example...
The existing implementation has poor numerical properties for
large arguments, so use the McGillicutty algorithm to improve
accuracy above 1e10.

The algorithm is described at
https://wikipedia.org/wiki/McGillicutty_Algorithm
-->

## Related issues

Requires https://github.com/pomerium/pomerium/pull/5961

[ENG-3135](https://linear.app/pomerium/issue/ENG-3135/ssh-auth-code-flow-ui-tuneups)

[ENG-3179](https://linear.app/pomerium/issue/ENG-3179/sshauth-ui-session-lifetime-info-not-accurate)

## User Explanation

<!-- How would you explain this change to the user? If this
change doesn't create any user-facing changes, you can leave
this blank. If filled out, add the `docs` label -->

## Checklist

- [x] reference any related issues
- [x] updated unit tests
- [x] add appropriate label (`enhancement`, `bug`, `breaking`,
`dependencies`, `ci`)
- [x] ready for review

0 of 27 new or added lines in 1 file covered. (0.0%)

183 existing lines in 8 files now uncovered.

29054 of 54829 relevant lines covered (52.99%)

85.22 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.5
/pkg/ssh/code/revoker.go
1
package code
2

3
import (
4
        "context"
5

6
        "github.com/cenkalti/backoff/v4"
7
        "google.golang.org/grpc/codes"
8
        "google.golang.org/grpc/status"
9
        "google.golang.org/protobuf/types/known/timestamppb"
10

11
        "github.com/pomerium/pomerium/pkg/grpc/databroker"
12
)
13

14
type revoker struct {
15
        clientB databroker.ClientGetter
16
}
17

18
var _ Revoker = (*revoker)(nil)
19

20
func NewRevoker(client databroker.ClientGetter) Revoker {
1✔
21
        return &revoker{
1✔
22
                clientB: client,
1✔
23
        }
1✔
24
}
1✔
25

26
func (r *revoker) RevokeCode(ctx context.Context, codeID CodeID) error {
2✔
27
        rec, err := r.clientB.GetDataBrokerServiceClient().
2✔
28
                Get(ctx, &databroker.GetRequest{
2✔
29
                        Type: "type.googleapis.com/session.SessionBindingRequest",
2✔
30
                        Id:   string(codeID),
2✔
31
                })
2✔
32

2✔
33
        if st, ok := status.FromError(err); ok && st.Code() == codes.NotFound {
3✔
34
                return nil
1✔
35
        } else if err != nil {
2✔
36
                return err
×
37
        }
×
38

39
        if rec.GetRecord().GetDeletedAt() != nil {
1✔
40
                return nil
×
41
        }
×
42

43
        rec.Record.DeletedAt = timestamppb.Now()
1✔
44

1✔
45
        _, err = r.clientB.GetDataBrokerServiceClient().
1✔
46
                Patch(ctx, &databroker.PatchRequest{
1✔
47
                        Records: []*databroker.Record{
1✔
48
                                rec.Record,
1✔
49
                        },
1✔
50
                })
1✔
51
        return err
1✔
52
}
53

54
func (r *revoker) RevokeIdentityBinding(ctx context.Context, bindingID BindingID) error {
2✔
55
        ibResp, err := r.clientB.GetDataBrokerServiceClient().
2✔
56
                Get(ctx, &databroker.GetRequest{
2✔
57
                        Type: "type.googleapis.com/session.IdentityBinding",
2✔
58
                        Id:   string(bindingID),
2✔
59
                })
2✔
60

2✔
61
        if st, ok := status.FromError(err); ok && st.Code() == codes.NotFound {
3✔
62
                return nil
1✔
63
        }
1✔
64

65
        if ibResp.GetRecord().GetDeletedAt() != nil {
1✔
66
                return nil
×
67
        }
×
68

69
        rec := ibResp.Record
1✔
70
        rec.DeletedAt = timestamppb.Now()
1✔
71
        _, err = r.clientB.GetDataBrokerServiceClient().Put(
1✔
72
                ctx,
1✔
73
                &databroker.PutRequest{
1✔
74
                        Records: []*databroker.Record{
1✔
75
                                rec,
1✔
76
                        },
1✔
77
                },
1✔
78
        )
1✔
79
        return err
1✔
80
}
81

82
func (r *revoker) RevokeSessionBinding(ctx context.Context, bindingID BindingID) error {
2✔
83
        sbResp, err := r.clientB.GetDataBrokerServiceClient().
2✔
84
                Get(ctx, &databroker.GetRequest{
2✔
85
                        Type: "type.googleapis.com/session.SessionBinding",
2✔
86
                        Id:   string(bindingID),
2✔
87
                })
2✔
88

2✔
89
        if st, ok := status.FromError(err); ok && st.Code() == codes.NotFound {
3✔
90
                return nil
1✔
91
        }
1✔
92
        if err != nil {
1✔
93
                return err
×
94
        }
×
95
        if sbResp.Record.GetDeletedAt() != nil {
1✔
96
                return nil
×
97
        }
×
98
        rec := sbResp.Record
1✔
99
        rec.DeletedAt = timestamppb.Now()
1✔
100
        _, err = r.clientB.GetDataBrokerServiceClient().
1✔
101
                Patch(ctx, &databroker.PatchRequest{
1✔
102
                        Records: []*databroker.Record{
1✔
103
                                rec,
1✔
104
                        },
1✔
105
                })
1✔
106
        return err
1✔
107
}
108

109
func (r *revoker) RevokeSessionBindingBySession(ctx context.Context, sessionID string) ([]*databroker.Record, error) {
3✔
110
        b := backoff.WithContext(backoff.NewExponentialBackOff(), ctx)
3✔
111
        recs, err := backoff.RetryWithData(func() ([]*databroker.Record, error) {
6✔
112
                return getSessionBindingBySession(ctx, r.clientB.GetDataBrokerServiceClient(), sessionID)
3✔
113
        }, b)
3✔
114
        if err != nil {
3✔
UNCOV
115
                return nil, err
×
UNCOV
116
        }
×
117
        if len(recs) == 0 {
4✔
118
                return []*databroker.Record{}, nil
1✔
119
        }
1✔
120
        for _, rec := range recs {
5✔
121
                rec.DeletedAt = timestamppb.Now()
3✔
122
        }
3✔
123
        _, err = r.clientB.GetDataBrokerServiceClient().Patch(ctx, &databroker.PatchRequest{
2✔
124
                Records: recs,
2✔
125
        })
2✔
126
        return recs, err
2✔
127
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc