Skip to content

Commit 90542eb

Browse files
authored
Merge pull request #146 from unisoncomputing/cp/admin-create-org
Add admin endpoint for creating orgs
2 parents 9a15544 + e3869aa commit 90542eb

File tree

3 files changed

+67
-2
lines changed

3 files changed

+67
-2
lines changed

src/Share/Web/Admin/API.hs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55

66
module Share.Web.Admin.API where
77

8+
import Servant
89
import Share.IDs
910
import Share.OAuth.Session
1011
import Share.Web.Admin.Types
11-
import Servant
1212

1313
type API =
1414
AuthenticatedSession :> UnauthenticatedAPI
@@ -21,6 +21,7 @@ type UnauthenticatedAPI =
2121
:> ( ("delete-user" :> DeleteUserEndpoint)
2222
)
2323
)
24+
:<|> ("orgs" :> "create" :> AdminCreateOrgEndpoint)
2425

2526
type CreateMissingLooseCodeMappingsEndpoint =
2627
Post '[JSON] ()
@@ -54,3 +55,7 @@ type AddCloudUserEndpoint =
5455
type RemoveCloudUserEndpoint =
5556
ReqBody '[JSON] RemoveCloudUserRequest
5657
:> Delete '[JSON] ()
58+
59+
type AdminCreateOrgEndpoint =
60+
ReqBody '[JSON] AdminCreateOrgRequest
61+
:> Post '[JSON] AdminCreateOrgResponse

src/Share/Web/Admin/Impl.hs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module Share.Web.Admin.Impl where
88

99
import Data.Either (partitionEithers)
1010
import Data.Time qualified as Time
11+
import Servant
1112
import Share.IDs
1213
import Share.Postgres qualified as PG
1314
import Share.Postgres.Admin qualified as Admin
@@ -20,7 +21,8 @@ import Share.Web.Admin.Types
2021
import Share.Web.App
2122
import Share.Web.Authorization qualified as AuthZ
2223
import Share.Web.Errors
23-
import Servant
24+
import Share.Web.Share.Orgs.Operations qualified as OrgOps
25+
import Share.Web.Share.Orgs.Queries qualified as OrgQ
2426
import Unison.Util.Monoid qualified as Monoid
2527

2628
-- | Ensure we have name lookups for views for this user.
@@ -69,13 +71,21 @@ removeFromCatalogCategoryEndpoint !_authzReceipt removals = do
6971
respondError (EntityMissing (ErrorID "catalog-categories:missing") msg)
7072
pure NoContent
7173

74+
createOrgEndpoint :: AuthZ.AuthZReceipt -> AdminCreateOrgRequest -> WebApp AdminCreateOrgResponse
75+
createOrgEndpoint !authZReceipt AdminCreateOrgRequest {orgName, orgHandle, orgEmail, orgAvatarUrl, orgOwner, isCommercial} = do
76+
User {user_id = ownerUserId} <- PGO.expectUserByHandle orgOwner
77+
PG.runTransactionOrRespondError $ do
78+
orgId <- OrgOps.createOrg authZReceipt orgName orgHandle orgEmail orgAvatarUrl ownerUserId ownerUserId isCommercial
79+
AdminCreateOrgResponse <$> OrgQ.orgDisplayInfoOf id orgId
80+
7281
server :: ServerT Admin.API WebApp
7382
server authedSession =
7483
let catalogServer authzReceipt = addToCatalogCategoryEndpoint authzReceipt :<|> removeFromCatalogCategoryEndpoint authzReceipt
7584
in hoistServer (Proxy @Admin.UnauthenticatedAPI) requireAdmin $
7685
catalogServer authzReceipt
7786
:<|> ( \userHandle -> deleteUserEndpoint authzReceipt userHandle
7887
)
88+
:<|> createOrgEndpoint authzReceipt
7989
where
8090
-- Require that the user has re-authenticated within the last 2 hours in order to
8191
-- perform admin actions.

src/Share/Web/Admin/Types.hs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
module Share.Web.Admin.Types where
55

66
import Data.Aeson
7+
import Data.Text (Text)
78
import Data.Time (Day)
89
import Share.IDs
10+
import Share.Utils.URI
11+
import Share.Web.Share.DisplayInfo.Types (OrgDisplayInfo)
912

1013
data ProjectCategory = ProjectCategory
1114
{ categoryName :: CategoryName,
@@ -46,3 +49,50 @@ data DeleteUserRequest = DeleteUserRequest
4649
instance FromJSON DeleteUserRequest where
4750
parseJSON = withObject "DeleteUserRequest" $ \o ->
4851
DeleteUserRequest <$> o .: "currentDate"
52+
53+
data AdminCreateOrgRequest = AdminCreateOrgRequest
54+
{ orgName :: Text,
55+
orgHandle :: OrgHandle,
56+
orgEmail :: Maybe Email,
57+
orgAvatarUrl :: Maybe URIParam,
58+
orgOwner :: UserHandle,
59+
isCommercial :: Bool
60+
}
61+
deriving (Show)
62+
63+
instance FromJSON AdminCreateOrgRequest where
64+
parseJSON = withObject "AdminCreateOrgRequest" $ \o -> do
65+
orgName <- o .: "name"
66+
orgHandle <- o .: "handle"
67+
orgEmail <- o .:? "email"
68+
orgAvatarUrl <- o .:? "avatarUrl"
69+
orgOwner <- o .: "owner"
70+
isCommercial <- o .:? "isCommercial" .!= False
71+
pure AdminCreateOrgRequest {..}
72+
73+
instance ToJSON AdminCreateOrgRequest where
74+
toJSON AdminCreateOrgRequest {..} =
75+
object
76+
[ "name" .= orgName,
77+
"handle" .= orgHandle,
78+
"email" .= orgEmail,
79+
"avatarUrl" .= orgAvatarUrl,
80+
"owner" .= orgOwner,
81+
"isCommercial" .= isCommercial
82+
]
83+
84+
data AdminCreateOrgResponse = AdminCreateOrgResponse
85+
{ org :: OrgDisplayInfo
86+
}
87+
deriving (Show)
88+
89+
instance FromJSON AdminCreateOrgResponse where
90+
parseJSON = withObject "AdminCreateOrgResponse" $ \o -> do
91+
org <- o .: "org"
92+
pure AdminCreateOrgResponse {..}
93+
94+
instance ToJSON AdminCreateOrgResponse where
95+
toJSON AdminCreateOrgResponse {..} =
96+
object
97+
[ "org" .= org
98+
]

0 commit comments

Comments
 (0)