Skip to content
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

Feature/legalhold tokens #761

Merged
merged 77 commits into from
Sep 5, 2019
Merged

Feature/legalhold tokens #761

merged 77 commits into from
Sep 5, 2019

Conversation

jschaul
Copy link
Member

@jschaul jschaul commented May 20, 2019

(see also note in 2483ac1)

Adds new token types to:

  • zauth
  • libzauth
  • nginx-auth-module

token generation and storage in brig

  • implement legal hold user/access token login /i/legalhold/login
  • implement legal hold token refresh /legalhold/access
  • throw error in the edge case where /i/legalhold/login is used to create a session legal hold token (not a possible code path in the current implementation but possible type wise - see TODO undefined in current changeset
  • integration test in legal hold tests: legal hold login leads to a lu cookie and a la access token.
  • integration tests: legal hold login cookie can be refreshed and revoked (many of the same tests as done here
  • make use of /i/legalhold-login (instead of current /i/sso-login)

end-to-end test using ACL, nginz route configuration

  • adjust deploy/services-demo/conf/nginz/zauth_acl.txt (as well as the other 2 configuration places) to allow the routes needed by the legal hold service

  • manual or integration test to check the change in nginx-auth-module is working (So far there are no tests testing nginz - except the smoketests) : 1) creating a token by talking to brig directly under /i/legalhold/login and 2) making a request to nginz using that token on a route allowed by the zauth_acl and making sure nginz is allowing a valid legalhold token through.

  • Pick one of two options to deal with token refresh endpoint:

  1. keep /access and /legalhold/access separate (in which case /legalhold/access needs to be mapped to brig in the nginx configurations (in all 3 places)
  2. merge /access and /legalhold/access endpoints (in which case nginz config doesn't need to be adjusted - the nginz config change in this PR can be undone), instead the types on that endpoint need to probably be Either UserToken LegalHoldUserToken (see e.g. https://github.com/wireapp/wire-server/blob/develop/services/brig/src/Brig/API.hs#L1216-L1217 an example Either endpoint).
  • fix galley tests with the new requirement that legalhold users = team users
  • logout & cookie cleanup test

Finally, after merging and deploying, ensure legal hold service can reach all its necessary routes (make sure all nginx configs are adjusted and possibly /access to changed to /legalhold/access in the legal hold service (depending on the choice in the task above)

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.

I took a quick look. It's a lot of boilerplate, but simple (which is good) and sound (also good) as far as I can tell.

-- B = Bot
-- P = Provider
-- LA = LegalHold Access (Used as short-lived token for LegalHold Service)
-- LU = LegalHold User (Used as a cookie for LegalHold Service to refresh access tokens)
Copy link
Contributor

Choose a reason for hiding this comment

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

now i'm wondering if LD (legalhold device) isn't a better name. less symmetrical, but more accurate. no strong opinion, though.

Copy link
Contributor

Choose a reason for hiding this comment

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

you could also move the list from this comment into the declaration:

data Type
    = A  --^ Access (...)
    | B  --^ ...
...

Copy link
Member Author

Choose a reason for hiding this comment

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

you could also move ...

thanks!

now i'm wondering if LD (legalhold device) ...

I prefer the symmetrical name, I think.

@fisx fisx mentioned this pull request May 31, 2019
8 tasks
jschaul and others added 3 commits July 10, 2019 20:35
The problem was that there was nothing in the context of
'newAccessToken' that would tell the type checker what the type
of (the type variables in the type of) 'Nothing' should be.
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.

(more comments coming up...)

services/brig/src/Brig/User/API/Auth.hs Show resolved Hide resolved
services/brig/src/Brig/User/API/Auth.hs Show resolved Hide resolved
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! done with everything but the tests. i'll wait for you to confirm they are done, then i'll review them.

services/brig/src/Brig/User/Auth.hs Outdated Show resolved Hide resolved
services/brig/src/Brig/User/Auth.hs Outdated Show resolved Hide resolved
services/brig/src/Brig/User/Auth.hs Outdated Show resolved Hide resolved
services/brig/src/Brig/API.hs Outdated Show resolved Hide resolved
const 403 === statusCode

putLegalHoldEnabled tid LegalHoldEnabled galley -- enable it for this team
_rs <- legalHoldLogin brig (LegalHoldLogin alice (Just defPassword) Nothing) PersistentCookie
Copy link
Contributor

Choose a reason for hiding this comment

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

Fail again here at the moment LH is enabled for team, but not for member?

Copy link
Member Author

Choose a reason for hiding this comment

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

That should be tested as part of galley's legal hold tests (if it's not, it should get added there, but it's not related to this PR)

t = decodeToken rs
-- ensure nginz allows refresh at /access
_rs <- post (n . path "/access" . cookie c . header "Authorization" ("Bearer " <> (toByteString' t))) <!! do
const 200 === statusCode
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is the line that the comment in 114 refers to. You could move the comment here (not tested):

Suggested change
const 200 === statusCode
assertEqual "/access (requires that private key on nginz and public key on brig match)"
(const 200) statusCode

Copy link
Member Author

Choose a reason for hiding this comment

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

The Bilge.assert and the HUnit.assert don't work well together, so the above doesn't compile, but I can do this:

_rs <- get (n . path "/clients" . header "Authorization" ("Bearer " <> (toByteString' t)))
liftIO $ assertEqual "Ensure nginz is started. Ensure nginz and brig share the same private/public zauth keys. Ensure ACL file is correct." 200 (statusCode _rs)

Copy link
Contributor

Choose a reason for hiding this comment

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

jschaul and others added 6 commits August 30, 2019 16:09
* Add json logging and logging  (#828)  (#836)

* Add logs for team operations
* Add logging for legalhold

* Json logging (#836)

* Allow to set log format
The old netstrings option is now deprecated, use logFormat instead.
logFormat takes presedence of netstrings if both are set.
If none are set, log format defaults to Plain
* Implement json renderer for tinylog

* Specialize the error cases on conversation lookup. (#841)

Getting a conversation you left will now give 403 access-denied, not 404 not-found.

* Feature Flags in galley options. (#825)

* Feature flags in galley options file.

* Honour sso feature flag.

* Honour legalhold feature flag (test).

* Honour legalhold feature flag (handler).

* Disable all LH tests if feature is disabled.

* Check options settings for feature flag.

* Avoid catch-all pattern.

Catch-all patterns are not future-proof if constructors for new
falvors of "disabled" are added.
This reverts commit b01fd8c.
fisx and others added 2 commits September 3, 2019 10:06
Conflicts:
services/brig/src/Brig/User/Auth.hs
services/brig/src/Brig/User/Auth/Cookie.hs
services/brig/test/integration/API/User/Auth.hs
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.

Some remaining open questions (besides the new comments in the code), for our call:

I would like to be walked through the rust code. The changes look sound, but I'm not very confident I haven't overlooked anything in my review.

I would also like to go through how disabeling LH on a per-team or per-instance level affects teams that already have LH devices running.

Do these need to be resolved?:

git grep -Hn -B2 -A2 TODO services/galley/src/Galley/API/LegalHold.hs
services/galley/src/Galley/API/LegalHold.hs-199-    LHService.confirmLegalHold clientId tid uid legalHoldAuthToken
services/galley/src/Galley/API/LegalHold.hs-200-    LegalHoldData.setUserLegalHoldStatus tid uid UserLegalHoldEnabled
services/galley/src/Galley/API/LegalHold.hs:201:    -- TODO: send event at this point (see also:
services/galley/src/Galley/API/LegalHold.hs-202-    -- https://github.com/wireapp/wire-server/pull/802#pullrequestreview-262280386)
services/galley/src/Galley/API/LegalHold.hs-203-    pure empty
--
services/galley/src/Galley/API/LegalHold.hs-238-        LHService.removeLegalHold tid uid
services/galley/src/Galley/API/LegalHold.hs-239-        LegalHoldData.setUserLegalHoldStatus tid uid UserLegalHoldDisabled
services/galley/src/Galley/API/LegalHold.hs:240:        -- TODO: send event at this point (see also: related TODO in this module in
services/galley/src/Galley/API/LegalHold.hs-241-        -- 'approveDevice' and
services/galley/src/Galley/API/LegalHold.hs-242-        -- https://github.com/wireapp/wire-server/pull/802#pullrequestreview-262280386)

let mtoken = (fromByteString (cookie_value ck)) :: Maybe (ZAuth.Token u)
assertBool "cookie token exists" (isJust mtoken)
let (Just token) = mtoken
assertBool "cookie token has correct type" ((token^.ZAuth.header.ZAuth.typ) == ZAuth.zauthType @u)
Copy link
Contributor

Choose a reason for hiding this comment

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

very nit-picky stuff, leading to a question that maybe genuinely interesting in the end:

  • I feel strongly we should require operators be surrounded spaces in our coding style. This is a good case to motivate this rule: the double-use of . for module qualification and function composition is very hard to read.
  • The error message from pattern match failure in line 875 is just as good as the one from the assertion in 874, so this code can be simplified.
  • I personally like type information best where a name is bound (ie., introduced).
  • Too many parens. :)

So this could be rewritten:

    let Just (token :: ZAuth.Token u) = fromByteString (cookie_value ck)
        tokentype = ZAuth.zauthType @u
    assertBool "cookie token has correct type" $ token ^. ZAuth.header . ZAuth.typ == tokentype

... and then I still have one more question: Can token really be parsed if it fails the subsequent assertion? Should it?

@@ -52,16 +53,16 @@ notifyClientsAboutLegalHoldRequest requesterUid targetUid lastPrekey' = do
. json (LegalHoldClientRequest requesterUid lastPrekey')
. expect2xx

getLegalHoldAuthToken :: UserId -> Galley OpaqueAuthToken
getLegalHoldAuthToken uid = do
getLegalHoldAuthToken :: UserId -> Maybe PlainTextPassword -> Galley OpaqueAuthToken
Copy link
Contributor

Choose a reason for hiding this comment

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

I am right that this is because some team members may have a password, and of course we want that password to be provided as an extra safety hook if a user approves a LH device, and we just forgot about that in the earlier part of the implementation?

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.

after a last round of pairing over the code, we agreed that it's done! (the remaining open questions are unrelated to this PR.)

@jschaul jschaul merged commit fdda052 into develop Sep 5, 2019
@jschaul jschaul deleted the feature/legalhold-tokens branch September 5, 2019 17:18
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.

None yet

3 participants