Skip to content

Conversation

akshaymankar
Copy link
Member

@akshaymankar akshaymankar commented Feb 10, 2022

https://wearezeta.atlassian.net/browse/SQCORE-1168

Noteworthy things:

  • I servantified POST /i/users because it had pretty much the same API and was using the same types.
  • While registering a user into a team, if the team has legal hold, the user can only be added if the fanoutLimit has not been reached. This check happens in galley, which generates a Wai.Error, brig just throws this error and so isn't aware of internals. This kind of error cannot be transformed into and ErrorDescription. So, for now (until galley's internal API is servantiified), brig throws this error using throwM, this error gets caught and handled by the Handler monad when it executes requests. This is of course not ideal. But hopefully we get to servantify Galley's internal endpoints and we can get rid of this hack.
  • The parser for NewUser is fairly complex some fields depend on other fields. To help with this, I created NewUserRaw which just parses individual fields. The schema for NewUser type uses withParser to do the validation and make composite fields.
  • Remove ToJSON/FromJSON for UserIdentity, use Schema for User. The ToJSON for UserIdentity encoded nulls, but every other object which used it didn't encode nulls. So, it was better to remove it.

Checklist

  • The PR Title explains the impact of the change.
  • The PR description provides context as to why the change should occur and what the code contributes to that effect. This could also be a link to a JIRA ticket or a Github issue, if there is one.
  • changelog.d contains the following bits of information (details):
    • A file with the changelog entry in one or more suitable sub-sections. The sub-sections are marked by directories inside changelog.d.

@akshaymankar akshaymankar force-pushed the akshaymankar/servantify-register branch 2 times, most recently from 0fe8259 to 5ede06a Compare February 16, 2022 14:46
@akshaymankar akshaymankar changed the title [WIP] Brig: Servantify POST /register endpoint Brig: Servantify POST /register and POST /i/users endpoint Feb 16, 2022
@akshaymankar akshaymankar marked this pull request as ready for review February 16, 2022 14:55
@akshaymankar akshaymankar marked this pull request as draft February 16, 2022 14:58
@akshaymankar akshaymankar marked this pull request as ready for review February 16, 2022 15:36
@akshaymankar akshaymankar requested review from fisx and pcapriotti and removed request for fisx February 16, 2022 15:44
Copy link
Contributor

@fisx fisx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but I haven't gone enough into the details to confidently approve yet. Have you taken a look at the swagger output?

-- those to enrich 'Wire.API.User.RegisterError' and ensure that these errors
-- also show up in swagger. Currently, the error returned by this endpoint is
-- thrown in IO, we could then refactor that to be thrown in `ExceptT
-- RegisterError`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm perfectly comfortable with waiting for polysemy with this, but sure, we can also touch it again when the internal API is servantified.

-- details.
--
-- You should have received a copy of the GNU Affero General Public License along
-- with this program. If not, see <https://www.gnu.org/licenses/>.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tripped over this and ran headroom again just to be sure, and there were changes. Small commit coming up.

newUserExpires <- o A..:? "expires_in"
newUserExpiresIn <- case (newUserExpires, newUserIdentity) of
-- | Raw representation of 'NewUser' to help with writing Schema instances.
data NewUserRaw = NewUserRaw
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so much nicer, thanks!

Comment on lines 50 to 51
eitherToParser (Left e) = fail e
eitherToParser (Right a) = pure a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
eitherToParser (Left e) = fail e
eitherToParser (Right a) = pure a
eitherToParser = either fail pure

is this even worth a new name? Possibly. Please ignore me. :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, we can just use either fail pure directly. Short and clear.

Comment on lines +159 to +160
ok <- isWhiteListed key
unless ok (throwError e)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@pcapriotti pcapriotti left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

One thing I'm not sure of is the huge list of error responses for the register endpoint. Even with polysemy, that corresponds to a huge list of individual error effects, which is a pain to manage. It's also not so great documentation, IMHO, since it shows way too much detail.

I think it would be nicer to have groupings of errors, like "registration error", "authentication error" etc... Then we could document each group separately (this could even be somewhat automated). We have done this sort of thing with federation errors, where it was pretty obvious that showing 20 possible error responses for basically each endpoint would have been insane.

@@ -802,6 +835,24 @@ data NewTeamUser
deriving stock (Eq, Show, Generic)
deriving (Arbitrary) via (GenericUniform NewTeamUser)

newTeamUserCode :: NewTeamUser -> Maybe InvitationCode
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These can be autogenerated by makePrisms. For example, instead of newTeamUserCode you can use preview _NewTeamMember.

@@ -181,7 +184,7 @@ instance ToJSON ActivationResponse where
instance FromJSON ActivationResponse where
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why doesn't this have a ToSchema instance?

Comment on lines 50 to 51
eitherToParser (Left e) = fail e
eitherToParser (Right a) = pure a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, we can just use either fail pure directly. Short and clear.

@fisx
Copy link
Contributor

fisx commented Feb 17, 2022

I think it would be nicer to have groupings of errors, like "registration error", "authentication error" etc... Then we could document each group separately (this could even be somewhat automated).

How do you guarantee that all errors in a group have the same code and label? Because that is the information we want to have for swagger code generation, no?

@fisx
Copy link
Contributor

fisx commented Feb 17, 2022

where it was pretty obvious that showing 20 possible error responses for basically each endpoint would have been insane.

Not obvious to me. Is it a run-time or compile-time performance issue? Or are you just unhappy with the length of the type signatures in characters?

@akshaymankar akshaymankar force-pushed the akshaymankar/servantify-register branch 2 times, most recently from 940a466 to 0bc874b Compare February 24, 2022 14:38
akshaymankar and others added 14 commits March 1, 2022 11:11
The ToJSON for UserIdentity encoded nulls, but every other object which used it
didn't encode nulls. So, it was better to remove it
This error cannot be easily encoding in the servant type as it is "dynamic" from
the perspective of brig. Once we servantify galley's internal API, we can know
about this error statically. This way we can catch it and throw it as a
`RegisterError` and it will show up in brigs a `RegisterError` and it will show
up in brig's swagger.
@akshaymankar akshaymankar force-pushed the akshaymankar/servantify-register branch from 45366d6 to 17ff786 Compare March 1, 2022 10:34
@akshaymankar akshaymankar force-pushed the akshaymankar/servantify-register branch from 41fd598 to cac1e96 Compare March 2, 2022 16:32
@akshaymankar akshaymankar merged commit dffa163 into develop Mar 3, 2022
@akshaymankar akshaymankar deleted the akshaymankar/servantify-register branch March 3, 2022 10:44
@zebot zebot mentioned this pull request Mar 7, 2022
fisx added a commit that referenced this pull request Mar 7, 2022
Noteworthy things:

- I servantified `POST /i/users` because it had pretty much the same API and was using the same types.
- While registering a user into a team, if the team has legal hold, the user can only be added if the fanoutLimit has not been reached. This check happens in galley, which generates a `Wai.Error`, brig just throws this error and so isn't aware of internals. This kind of error cannot be transformed into and `ErrorDescription`. So, for now (until galley's internal API is servantiified), brig throws this error using `throwM`, this error gets caught and handled by the `Handler` monad when it executes requests. This is of course not ideal. But hopefully we get to servantify Galley's internal endpoints and we can get rid of this hack.
- The parser for `NewUser` is fairly complex some fields depend on other fields. To help with this, I created `NewUserRaw` which just parses individual fields. The schema for `NewUser` type uses `withParser` to do the validation and make composite fields.
-  Remove ToJSON/FromJSON for UserIdentity, use Schema for User. The ToJSON for UserIdentity encoded nulls, but every other object which used it didn't encode nulls. So, it was better to remove it.

Co-authored-by: Matthias Fischmann <[email protected]>
@zebot zebot mentioned this pull request Mar 9, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants