Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
bc01c6b
Servantify /i-api
fisx Sep 30, 2022
d34073e
Serve servant api under path prefix.
fisx Sep 30, 2022
fa1647a
More servant end-points
fisx Sep 30, 2022
effcd1f
More servant end-points
fisx Sep 30, 2022
0402a5f
More servant end-points
fisx Sep 30, 2022
a3a592d
More servant end-points
fisx Sep 30, 2022
74ead40
More servant end-points
fisx Oct 1, 2022
bfa9fba
More servant end-points
fisx Oct 1, 2022
374b422
Keep wai-route routing table only for swagger1.2 (part 1).
fisx Oct 1, 2022
45cc63f
Keep wai-route routing table only for swagger1.2 (part 2).
fisx Oct 1, 2022
d3b869a
More servant end-points
fisx Oct 1, 2022
8859904
More servant end-points
fisx Oct 1, 2022
44b8413
Fun with schema-profunctor
fisx Oct 3, 2022
7c04763
More servant end-points (feature config)
fisx Oct 3, 2022
c70a193
More servant end-points (feature config)
fisx Oct 3, 2022
69a2437
Merge remote-tracking branch 'origin/develop' into fisx/servantify-st…
fisx Oct 3, 2022
07a6192
More servant end-points (feature config)
fisx Oct 4, 2022
021a387
More servant end-points
fisx Oct 4, 2022
7d1c0e1
Cleanup
fisx Oct 4, 2022
e8b9e18
Merge remote-tracking branch 'origin/develop' into fisx/servantify-st…
fisx Oct 4, 2022
da55eca
Fixup
fisx Oct 4, 2022
06f42da
Merge remote-tracking branch 'origin/develop' into fisx/servantify-st…
fisx Oct 5, 2022
fed95a3
Bug fix: make routes distinguishable by path.
fisx Oct 5, 2022
c153386
Update docs
fisx Oct 5, 2022
fe11502
Revert "Cleanup"
fisx Oct 5, 2022
17ea250
changelog
fisx Oct 5, 2022
9b7f614
Removed unused imports.
elland Oct 6, 2022
a41fd20
Merge remote-tracking branch 'refs/remotes/origin/fisx/servantify-ste…
fisx Oct 6, 2022
0d802cb
imports
fisx Oct 6, 2022
01c3643
Fixup
fisx Oct 6, 2022
31d31d0
Cleanup
fisx Oct 6, 2022
d9a5277
docs.
fisx Oct 6, 2022
fd30f2c
Merge remote-tracking branch 'origin/develop' into fisx/servantify-st…
fisx Oct 6, 2022
51348d5
hi ci
fisx Oct 6, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/5-internal/pr-2742
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Migrate stern to swagger2-ui (remaining backwards compatible with circulating backoffice images) (see also #2742 from last release) (#2744)
1 change: 1 addition & 0 deletions libs/galley-types/galley-types.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ library
, QuickCheck
, schema-profunctor
, string-conversions
, swagger2
, tagged
, text >=0.11
, time >=1.4
Expand Down
57 changes: 28 additions & 29 deletions libs/galley-types/src/Galley/Types/Teams/Intra.hs
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}

-- This file is part of the Wire Server implementation.
Expand Down Expand Up @@ -31,6 +36,8 @@ import Data.Aeson
import Data.Aeson.TH
import qualified Data.Currency as Currency
import Data.Json.Util
import qualified Data.Schema as S
import qualified Data.Swagger as Swagger hiding (schema)
import Data.Time (UTCTime)
import Imports
import Test.QuickCheck.Arbitrary (Arbitrary)
Expand All @@ -46,42 +53,34 @@ data TeamStatus
| Suspended
| PendingActive
deriving (Eq, Show, Generic)

instance ToJSON TeamStatus where
toJSON Active = String "active"
toJSON PendingDelete = String "pending_delete"
toJSON Deleted = String "deleted"
toJSON Suspended = String "suspended"
toJSON PendingActive = String "pending_active"

instance FromJSON TeamStatus where
parseJSON (String "active") = pure Active
parseJSON (String "pending_delete") = pure PendingDelete
parseJSON (String "deleted") = pure Deleted
parseJSON (String "suspended") = pure Suspended
parseJSON (String "pending_active") = pure PendingActive
parseJSON other = fail $ "Unknown TeamStatus: " <> show other
deriving (ToJSON, FromJSON, Swagger.ToSchema) via S.Schema TeamStatus

instance S.ToSchema TeamStatus where
schema =
S.enum @Text "Access" $
mconcat
[ S.element "active" Active,
S.element "pending_delete" PendingDelete,
S.element "deleted" Deleted,
S.element "suspended" Suspended,
S.element "pending_active" PendingActive
]

data TeamData = TeamData
{ tdTeam :: !Team,
tdStatus :: !TeamStatus,
tdStatusTime :: !(Maybe UTCTime) -- This needs to be a Maybe due to backwards compatibility
}
deriving (Eq, Show, Generic)

instance ToJSON TeamData where
toJSON (TeamData t s st) =
object $
"team" .= t
# "status" .= s
# "status_time" .= (toUTCTimeMillis <$> st)
# []

instance FromJSON TeamData where
parseJSON = withObject "team-data" $ \o -> do
TeamData <$> o .: "team"
<*> o .: "status"
<*> o .:? "status_time"
deriving (ToJSON, FromJSON, Swagger.ToSchema) via S.Schema TeamData

instance S.ToSchema TeamData where
schema =
S.object "TeamData" $
TeamData
<$> tdTeam S..= S.field "team" S.schema
<*> tdStatus S..= S.field "status" S.schema
<*> tdStatusTime S..= S.maybe_ (S.optField "status_time" utcTimeSchema)

data TeamStatusUpdate = TeamStatusUpdate
{ tuStatus :: !TeamStatus,
Expand Down
6 changes: 3 additions & 3 deletions libs/polysemy-wire-zoo/polysemy-wire-zoo.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ build-type: Simple
library
exposed-modules:
Polysemy.TinyLog
Wire.Sem.Concurrency
Wire.Sem.Concurrency.IO
Wire.Sem.Concurrency.Sequential
Wire.Sem.FromUTC
Wire.Sem.Logger
Wire.Sem.Logger.Level
Expand All @@ -25,9 +28,6 @@ library
Wire.Sem.Paging.Cassandra
Wire.Sem.Random
Wire.Sem.Random.IO
Wire.Sem.Concurrency
Wire.Sem.Concurrency.IO
Wire.Sem.Concurrency.Sequential

other-modules: Paths_polysemy_wire_zoo
hs-source-dirs: src
Expand Down
14 changes: 14 additions & 0 deletions libs/wire-api/src/Wire/API/Team/Feature.hs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ module Wire.API.Team.Feature
withLockStatus,
withUnlocked,
FeatureTTL,
FeatureTTLDays,
FeatureTTL' (..),
FeatureTTLUnit (..),
convertFeatureTTLDaysToSeconds,
Expand Down Expand Up @@ -971,6 +972,19 @@ data FeatureStatus
deriving (Arbitrary) via (GenericUniform FeatureStatus)
deriving (ToJSON, FromJSON, S.ToSchema) via (Schema FeatureStatus)

instance S.ToParamSchema FeatureStatus where
toParamSchema _ =
mempty
{ S._paramSchemaType = Just S.SwaggerString,
S._paramSchemaEnum = Just (A.String . toQueryParam <$> [(minBound :: FeatureStatus) ..])
}

instance FromHttpApiData FeatureStatus where
parseUrlPiece = maybe (Left "must be 'enabled' or 'disabled'") Right . fromByteString' . cs

instance ToHttpApiData FeatureStatus where
toUrlPiece = cs . toByteString'

typeFeatureStatus :: Doc.DataType
typeFeatureStatus =
Doc.string $
Expand Down
13 changes: 8 additions & 5 deletions libs/wire-api/src/Wire/API/Team/Member.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ module Wire.API.Team.Member
teamMemberJson,
setOptionalPerms,
setOptionalPermsMany,
teamMemberObjectSchema,

-- * TeamMemberList
TeamMemberList,
Expand Down Expand Up @@ -133,11 +134,13 @@ mkTeamMember ::
mkTeamMember uid perms inv = TeamMember (NewTeamMember uid perms inv)

instance ToSchema TeamMember where
schema =
object "TeamMember" $
TeamMember
<$> _newTeamMember .= newTeamMemberSchema
<*> _legalHoldStatus .= (fromMaybe defUserLegalHoldStatus <$> optFieldWithDocModifier "legalhold_status" (description ?~ lhDesc) schema)
schema = object "TeamMember" teamMemberObjectSchema

teamMemberObjectSchema :: ObjectSchema SwaggerDoc TeamMember
teamMemberObjectSchema =
TeamMember
<$> _newTeamMember .= newTeamMemberSchema
<*> _legalHoldStatus .= (fromMaybe defUserLegalHoldStatus <$> optFieldWithDocModifier "legalhold_status" (description ?~ lhDesc) schema)

instance ToSchema (TeamMember' 'Optional) where
schema =
Expand Down
16 changes: 16 additions & 0 deletions libs/wire-api/src/Wire/API/User/Identity.hs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ import SAML2.WebSSO.Test.Arbitrary ()
import qualified SAML2.WebSSO.Types as SAML
import qualified SAML2.WebSSO.Types.Email as SAMLEmail
import qualified SAML2.WebSSO.XML as SAML
import qualified Servant.API as S
import System.FilePath ((</>))
import qualified Test.QuickCheck as QC
import qualified Text.Email.Validate as Email.V
Expand Down Expand Up @@ -187,6 +188,12 @@ instance ToByteString Email where
instance FromByteString Email where
parser = parser >>= maybe (fail "Invalid email") pure . parseEmail

instance S.FromHttpApiData Email where
parseUrlPiece = maybe (Left "Invalid email") Right . fromByteString . cs

instance S.ToHttpApiData Email where
toUrlPiece = cs . toByteString'

instance Arbitrary Email where
arbitrary = do
localPart <- Text.filter (/= '@') <$> arbitrary
Expand Down Expand Up @@ -249,6 +256,9 @@ newtype Phone = Phone {fromPhone :: Text}
deriving stock (Eq, Ord, Show, Generic)
deriving (ToJSON, FromJSON, S.ToSchema) via (Schema Phone)

instance ToParamSchema Phone where
toParamSchema _ = toParamSchema (Proxy @Text)

instance ToSchema Phone where
schema =
over doc (S.description ?~ "E.164 phone number") $
Expand All @@ -260,6 +270,12 @@ instance ToByteString Phone where
instance FromByteString Phone where
parser = parser >>= maybe (fail "Invalid phone") pure . parsePhone

instance S.FromHttpApiData Phone where
parseUrlPiece = maybe (Left "Invalid phone") Right . fromByteString . cs

instance S.ToHttpApiData Phone where
toUrlPiece = cs . toByteString'

instance Arbitrary Phone where
arbitrary =
Phone . Text.pack <$> do
Expand Down
31 changes: 23 additions & 8 deletions tools/stern/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
Stern - Backoffice facade
Stern - Backoffice Facade
=========================

This tool can be used to create a very basic Backoffice tool to simplify performing operations on users and teams such as visualising their user profiles, suspending or even deleting accounts. It is used internally at Wire to provide customer support the means to respond to certain queries from our customers.
This is a simple web app based on [swagger-ui](https://swagger.io/tools/swagger-ui/) for performing operations on users and teams such as browsing their user profiles, suspending, or deleting accounts. It is used internally at Wire by our customer support team.

Stern provides a swagger interface that accesses multiple other services (mostly using internal endpoints) and is designed to be a simple way to create a basic backoffice functionality. The swagger interface is served at `<ip:stern_port>/stern/api-docs`
Stern is based on a swagger interface that accesses multiple other services (mostly using internal endpoints) and is designed to be a simple way to create a basic backoffice functionality. Point your browser at `http://<ip-or-host>:<port>/backoffice/api/swagger-ui/`; `<port>` is usually 8091.

## IMPORTANT NOTES

Expand All @@ -13,19 +13,34 @@ It is intended to be deployed in a private network and accessible only through a

Some endpoints (marked as such on the Swagger interface) depend on internal services (named galeb and ibis) that are not relevant for a generic wire server installation as they gather info from other internal systems at Wire (related to billing or other services) and as such will not work properly on installations without them.

### Legacy mode

stern used to be run together with a separate docker image that carried the swagger-ui frontend, while stern only served the swagger data and the actual rest api. This is not recommended any more, but until all the infrastructure everywhere has caught up with the new mode of operation, stern still delivers the old swagger1.2 data as before under the same path. For details see `./src/Stern/API/RoutesLegacy.hs`.

## How to run stern together with the rest of wire-server

TODO: This section is under construction

## How to run stern locally with the `services-demo`

Follow the instruction in [`deploy/services-demo/README.md`](../../deploy/services-demo/README.md),
using the `--run-backoffice` option, e.g. `deploy/sevices-demo/demo.sh --run-backoffice`
using the `--run-backoffice` option, e.g. `deploy/sevices-demo/demo.sh --run-backoffice`.

When you now open `localhost:8080/swagger-ui` in a browser, you can switch to the
"Back Office" tab.
Open `http://localhost:8091/backoffice/api/swagger-ui/` in a browser.
(Legacy mode: when you now open `localhost:8080/swagger-ui` in a
browser, you can switch to the "Back Office" tab.)

## Screenshots

![screen shot 1](screenshots/1.png)
![screen shot 2](screenshots/2.png)
![screen shot 1](screenshots/a.png)
![screen shot 2](screenshots/b.png)

# Legacy mode:

![screen shot 1](screenshots/legacy/1.png)
![screen shot 2](screenshots/legacy/2.png)

(one could argue that the old swagger-ui was a little more
end-user-friendly, to which one could respond that neither version is
intended for end-users, but for web-devs, and we should just spend a
week writing an elm app that does this right. :))
Binary file added tools/stern/screenshots/a.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added tools/stern/screenshots/b.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
File renamed without changes
File renamed without changes
Loading