1package signin
2
3import (
4 "context"
5 "errors"
6
7 "tug/internal/storage"
8 "tug/internal/transport/web"
9)
10
11type googleLinks struct {
12 a account
13}
14
15var _ web.GoogleLinks = googleLinks{}
16
17var googleProblems = []struct {
18 err error
19 want error
20}{
21 {storage.ErrGoogleLinkedElsewhere, web.ErrGoogleLinkedElsewhere},
22 {storage.ErrGoogleAlreadyLinked, web.ErrGoogleAlreadyLinked},
23 {storage.ErrGoogleNotLinked, web.ErrGoogleNotLinked},
24 {storage.ErrInvalid, web.ErrNoSession},
25}
26
27func googleError(err error) error {
28 for _, m := range googleProblems {
29 if errors.Is(err, m.err) {
30 return m.want
31 }
32 }
33 return err
34}
35
36func (g googleLinks) Link(ctx context.Context, p web.Principal, id web.GoogleIdentity) (web.AccountGoogleLink, error) {
37 link, err := g.a.s.LinkGoogle(ctx, g.a.principal(p), id.Subject)
38 if err != nil {
39 return web.AccountGoogleLink{}, googleError(err)
40 }
41 return web.AccountGoogleLink{LinkedAt: link.LinkedAt}, nil
42}
43
44func (g googleLinks) Unlink(ctx context.Context, p web.Principal) (web.AccountGoogleLink, error) {
45 link, _, err := g.a.s.UnlinkGoogle(ctx, g.a.principal(p))
46 if err != nil {
47 return web.AccountGoogleLink{}, googleError(err)
48 }
49 return web.AccountGoogleLink{LinkedAt: link.LinkedAt}, nil
50}