-
Notifications
You must be signed in to change notification settings - Fork 333
Brig: Servantify POST /register
and POST /i/users
endpoint
#2121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
0fe8259
to
5ede06a
Compare
POST /register
endpointPOST /register
and POST /i/users
endpoint
There was a problem hiding this 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`. |
There was a problem hiding this comment.
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/>. |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so much nicer, thanks!
eitherToParser (Left e) = fail e | ||
eitherToParser (Right a) = pure a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. :)
There was a problem hiding this comment.
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.
ok <- isWhiteListed key | ||
unless ok (throwError e) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok <- isWhiteListed key | |
unless ok (throwError e) | |
unlessM (isWhiteListed key) (throwError e) |
There was a problem hiding this 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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
eitherToParser (Left e) = fail e | ||
eitherToParser (Right a) = pure a |
There was a problem hiding this comment.
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.
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? |
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? |
940a466
to
0bc874b
Compare
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.
45366d6
to
17ff786
Compare
41fd598
to
cac1e96
Compare
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]>
https://wearezeta.atlassian.net/browse/SQCORE-1168
Noteworthy things:
POST /i/users
because it had pretty much the same API and was using the same types.Wai.Error
, brig just throws this error and so isn't aware of internals. This kind of error cannot be transformed into andErrorDescription
. So, for now (until galley's internal API is servantiified), brig throws this error usingthrowM
, this error gets caught and handled by theHandler
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.NewUser
is fairly complex some fields depend on other fields. To help with this, I createdNewUserRaw
which just parses individual fields. The schema forNewUser
type useswithParser
to do the validation and make composite fields.Checklist
changelog.d
.