|
| 1 | +{-# LANGUAGE RecordWildCards #-} |
| 2 | + |
| 3 | +-- This file is part of the Wire Server implementation. |
| 4 | +-- |
| 5 | +-- Copyright (C) 2026 Wire Swiss GmbH <opensource@wire.com> |
| 6 | +-- |
| 7 | +-- This program is free software: you can redistribute it and/or modify it under |
| 8 | +-- the terms of the GNU Affero General Public License as published by the Free |
| 9 | +-- Software Foundation, either version 3 of the License, or (at your option) any |
| 10 | +-- later version. |
| 11 | +-- |
| 12 | +-- This program is distributed in the hope that it will be useful, but WITHOUT |
| 13 | +-- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
| 14 | +-- FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more |
| 15 | +-- details. |
| 16 | +-- |
| 17 | +-- You should have received a copy of the GNU Affero General Public License along |
| 18 | +-- with this program. If not, see <https://www.gnu.org/licenses/>. |
| 19 | + |
| 20 | +module Wire.DomainRegistrationStore.Postgres |
| 21 | + ( interpretDomainRegistrationStoreToPostgres, |
| 22 | + ) |
| 23 | +where |
| 24 | + |
| 25 | +import Data.Id (TeamId) |
| 26 | +import Data.UUID (UUID) |
| 27 | +import Data.Vector (Vector) |
| 28 | +import Data.Vector qualified as Vector |
| 29 | +import Hasql.Statement qualified as Hasql |
| 30 | +import Hasql.TH |
| 31 | +import Imports hiding (lookup) |
| 32 | +import Polysemy |
| 33 | +import Wire.API.PostgresMarshall |
| 34 | +import Wire.DomainRegistrationStore |
| 35 | +import Wire.Postgres |
| 36 | + |
| 37 | +interpretDomainRegistrationStoreToPostgres :: |
| 38 | + (PGConstraints r) => |
| 39 | + InterpreterFor DomainRegistrationStore r |
| 40 | +interpretDomainRegistrationStoreToPostgres = interpret $ \case |
| 41 | + UpsertInternal dr -> upsertImpl dr |
| 42 | + LookupInternal domain -> lookupImpl domain |
| 43 | + LookupByTeamInternal tid -> lookupByTeamInternalImpl tid |
| 44 | + DeleteInternal domain -> deleteImpl domain |
| 45 | + |
| 46 | +upsertImpl :: (PGConstraints r) => StoredDomainRegistration -> Sem r () |
| 47 | +upsertImpl dr = |
| 48 | + runStatement dr upsertStatement |
| 49 | + where |
| 50 | + upsertStatement :: Hasql.Statement StoredDomainRegistration () |
| 51 | + upsertStatement = |
| 52 | + lmapPG |
| 53 | + [resultlessStatement|INSERT INTO domain_registration |
| 54 | + (domain, domain_redirect, team_invite, idp_id, backend_url, |
| 55 | + team, dns_verification_token, ownership_token_hash, authorized_team, webapp_url) |
| 56 | + VALUES |
| 57 | + ($1 :: text, $2 :: int?, $3 :: int?, $4 :: uuid?, $5 :: bytea?, |
| 58 | + $6 :: uuid?, $7 :: text?, $8 :: bytea?, $9 :: uuid?, $10 :: bytea?) |
| 59 | + ON CONFLICT (domain) DO UPDATE |
| 60 | + SET domain_redirect = ($2 :: int?), |
| 61 | + team_invite = ($3 :: int?), |
| 62 | + idp_id = ($4 :: uuid?), |
| 63 | + backend_url = ($5 :: bytea?), |
| 64 | + team = ($6 :: uuid?), |
| 65 | + dns_verification_token = ($7 :: text?), |
| 66 | + ownership_token_hash = ($8 :: bytea?), |
| 67 | + authorized_team = ($9 :: uuid?), |
| 68 | + webapp_url = ($10 :: bytea?) |
| 69 | + |] |
| 70 | + |
| 71 | +lookupImpl :: (PGConstraints r) => DomainKey -> Sem r (Maybe StoredDomainRegistration) |
| 72 | +lookupImpl domain = |
| 73 | + runStatement domain selectStatement |
| 74 | + where |
| 75 | + selectStatement :: Hasql.Statement DomainKey (Maybe StoredDomainRegistration) |
| 76 | + selectStatement = |
| 77 | + dimapPG @Text @DomainKey @(Maybe DomainRegistrationRow) @(Maybe StoredDomainRegistration) $ |
| 78 | + [maybeStatement|SELECT (domain :: text), (domain_redirect :: int?), (team_invite :: int?), |
| 79 | + (idp_id :: uuid?), (backend_url :: bytea?), (team :: uuid?), |
| 80 | + (dns_verification_token :: text?), (ownership_token_hash :: bytea?), |
| 81 | + (authorized_team :: uuid?), (webapp_url :: bytea?) |
| 82 | + FROM domain_registration |
| 83 | + WHERE domain = ($1 :: text) |
| 84 | + |] |
| 85 | + |
| 86 | +lookupByTeamInternalImpl :: (PGConstraints r) => TeamId -> Sem r [StoredDomainRegistration] |
| 87 | +lookupByTeamInternalImpl tid = do |
| 88 | + rows <- runStatement tid selectByTeamStatement |
| 89 | + pure $ Vector.toList rows |
| 90 | + where |
| 91 | + selectByTeamStatement :: Hasql.Statement TeamId (Vector StoredDomainRegistration) |
| 92 | + selectByTeamStatement = |
| 93 | + dimapPG @UUID @TeamId @(Vector DomainRegistrationRow) @(Vector StoredDomainRegistration) $ |
| 94 | + [vectorStatement|SELECT (domain :: text), (domain_redirect :: int?), (team_invite :: int?), |
| 95 | + (idp_id :: uuid?), (backend_url :: bytea?), (team :: uuid?), |
| 96 | + (dns_verification_token :: text?), (ownership_token_hash :: bytea?), |
| 97 | + (authorized_team :: uuid?), (webapp_url :: bytea?) |
| 98 | + FROM domain_registration |
| 99 | + WHERE authorized_team = ($1 :: uuid) |
| 100 | + |] |
| 101 | + |
| 102 | +deleteImpl :: (PGConstraints r) => DomainKey -> Sem r () |
| 103 | +deleteImpl domain = |
| 104 | + runStatement domain deleteStatement |
| 105 | + where |
| 106 | + deleteStatement :: Hasql.Statement DomainKey () |
| 107 | + deleteStatement = |
| 108 | + lmapPG |
| 109 | + [resultlessStatement|DELETE FROM domain_registration |
| 110 | + WHERE domain = ($1 :: text) |
| 111 | + |] |
0 commit comments