-
Notifications
You must be signed in to change notification settings - Fork 17
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
Add support for event specific password protection #1244
base: next
Are you sure you want to change the base?
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
8e8763f
to
30d55f1
Compare
8ed23b8
to
e252587
Compare
e252587
to
a2e4d24
Compare
a2e4d24
to
402869f
Compare
402869f
to
5fd35f1
Compare
5fd35f1
to
aca0209
Compare
aca0209
to
e4630aa
Compare
df91940
to
ac46ed4
Compare
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.
Thanks for tackling this huge feature! The PR was nice to review commit by commit. And while below I have written quite a few comments, I think the general direction is absolutely correct, and all remarks are just "local problems", not really anything that requires rethinking everything.
Apart from the inline comments, while testing it I noticed these things:
- The "in flight" circle still spins when invalid credentials are entered on video page. Once the error is shown, the spinner should disappear. This only happens when entering them incorrectly twice... what.
- The whole page flashes when submitting credentials. Also, if the credentials were wrong, this means the entered credentials disappear, which is annoying if u only need to correct a typo.
I have to re-test everything again, but I think this is already a long enough review. I can test again after these things are fixed.
-- For convenience, all read roles are also copied over to preview roles. | ||
-- Removing any roles from read will however _not_ remove them from preview, as they | ||
-- might also have been added separately and we can't really account for that. |
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.
Mhhh this is tricky. So the thing you describe isn't great, right? Because yes, if we mix them together, we have no idea what was originally set. Just so I understand correctly: the only (as in 'singular', not to diminish the importance) reason to mix them together is to have easier queries, right? So we don't have to check both columns everywhere? Or is there more to it?
My gut feeling is to keep them separate. We might have already talked about this, in which case I forgot and would be happy to be reminded :D
Maybe in the future, the ACL selector allows users to select preview, read or write. Well mh no, that could work with either model. I suppose there is no operation that allows users to "just remove a single action permission" from an event, which is what would trigger the thing you mentioned here. The harvest process would also overwrite the whole ACL and wouldn't cause a problem with either model.
So right now I cannot think of a case where your model would break... mhhh. I might think about it a bit more.
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.
is there more to it?
no, I don't think there is.
We might have already talked about this
You suggested doing it like this when we first planned the whole thing. I then said "no lets not, because reasons™". But when implementing it, I realized that I actually find it nicer to have only one filter/check for access things, taking the cue from how read
and write
roles are handled (whenever something requiring read
access is checked, it's not necessary to also check for write
, as read
also includes all write
roles).
This comment was marked as resolved.
This comment was marked as resolved.
e4630aa
to
2632d55
Compare
Optional event credentials are now storable in DB, and the are some endpoints to check whether an event is password protected. This also adds a dummy check to `authenticated_data`, to simulate event authentication. Will be extended/replaced in a later commit.
c169436
to
c7b710b
Compare
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.
This is ready for review again. I tried to address everything you commented on and added a few commits to fix some more stuff I noticed myself, and also to allow storing the series id when authenticating for an event, so that each event of that series will be unlocked.
-- For convenience, all read roles are also copied over to preview roles. | ||
-- Removing any roles from read will however _not_ remove them from preview, as they | ||
-- might also have been added separately and we can't really account for that. |
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.
is there more to it?
no, I don't think there is.
We might have already talked about this
You suggested doing it like this when we first planned the whole thing. I then said "no lets not, because reasons™". But when implementing it, I realized that I actually find it nicer to have only one filter/check for access things, taking the cue from how read
and write
roles are handled (whenever something requiring read
access is checked, it's not necessary to also check for write
, as read
also includes all write
roles).
frontend/src/ui/Video.tsx
Outdated
@@ -43,6 +45,10 @@ export const Thumbnail: React.FC<ThumbnailProps> = ({ | |||
}) => { | |||
const { t } = useTranslation(); | |||
const isDark = useColorScheme().scheme === "dark"; | |||
const authenticatedData = useAuthenticatedDataQuery(keyOfId(event.id)); |
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.
Yeah I don't like that either, would prefer another solution (which I don't have obv).
First I thought this would only send a couple of requests anyway, but when there are one or more blocks of pw-protected series with a lot of videos on a page, there will be a lot of requests.
frontend/src/ui/Video.tsx
Outdated
@@ -43,6 +45,10 @@ export const Thumbnail: React.FC<ThumbnailProps> = ({ | |||
}) => { | |||
const { t } = useTranslation(); | |||
const isDark = useColorScheme().scheme === "dark"; | |||
const authenticatedData = useAuthenticatedDataQuery(keyOfId(event.id)); |
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 also looked into replacing this specific call in Thumbnail
, but that gets somewhat complicated indeed. Not sure if it's worth sinking more time into it for now.
@oas777 you can test this (or at least see it in action) with https://pr1244.tobira.opencast.org/test-videos/pw-proc. |
Thanks, @owi92, access does work as expected. And Bitwarden seems to identify this as access information it can store ... Two remarks on wording:
|
Agree 100% on "Name"/"Username" being weird in this context. "Kennung"/"Identifier" is good! Thank you for the suggestion. |
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.
Did a review of your latest changes, resolving almost all inline comments, but adding a few more. Only small ones though.
I am not done with this PR yet, but I thought I'd already send these things out. Reminder to myself what I still want to do:
- Think about the remaining unresolved line comments from my previous review
- Think about the solution to avoid flashing the page
- Think about the
React.Context
you added - Look at the second new migration
- Test the deployment
- Check text search
To do that I want to re-review routes/Video.tsx
, both SQL migrations and the API docs for previewRoles
.
frontend/src/routes/Embed.tsx
Outdated
const authorizedData = useAuthenticatedDataQuery( | ||
event.id, | ||
event.series?.id, | ||
{ authorizedData: event.authorizedData }, | ||
); | ||
|
||
return authorizedData | ||
? <Player event={{ ...event, authorizedData }} /> | ||
: <PreviewPlaceholder embedded {...{ event }}/>; | ||
}; |
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 think this is broken? Like, entering the credentials on the embed route only shows a spinner but otherwise does nothing.
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 forgot to add the context.
That reminds me, since you also wanted to think about the context:
I tried moving that into a custom hook like the one in PlayerContext.tsx
, but using that weirdly didn't have the same effect (read: it didn't have any effect) as just defining the state and context individually for each file it's needed in, like I do it now.
If, by any chance, you have some time and motivation to try this out, I'd be interested if you can get that to work. Of course, that only makes sense if we decide to stick with the context solution.
I agree we switch to "Kennung"/"Identifier". But what about the explanation text then? It's currently this:
Is the second sentence still necessary then? Also the first sentence: it's incorrect in our general Tobira implementation as the password is not necessarily associated with the series. Also: yeah I'm presented with a id/password prompt, obviously I should enter username and password to access the video. So maybe just completely remove the note? @oas777 |
Thanks for chiming in, @LukasKalbertodt. Obviously, the explanation text should be modified accordingly: "Please enter the identifier and the password you have received to access this video; please note that these are not your login credentials." As for the second sentence, this is to differentiate the approach from authenticating "the right way" and very important here at ETH for the confusion this causes. But I see how this is not relevant for everyone else. Can we add this "locally"? |
c7b710b
to
d2662a7
Compare
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.
Ready for the next pass.
Regarding the explanation text:
"please note that these are not your login credentials."
Can we add this "locally"?
We could, but I wouldn't mind keeping this for now. Even if we would only prompt for a password, I don't think having this clarification would hurt. Also, having no note at all would just make the authentication mask be really lonely in the vastness of that empty placeholder.
frontend/src/routes/Embed.tsx
Outdated
const authorizedData = useAuthenticatedDataQuery( | ||
event.id, | ||
event.series?.id, | ||
{ authorizedData: event.authorizedData }, | ||
); | ||
|
||
return authorizedData | ||
? <Player event={{ ...event, authorizedData }} /> | ||
: <PreviewPlaceholder embedded {...{ event }}/>; | ||
}; |
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 forgot to add the context.
That reminds me, since you also wanted to think about the context:
I tried moving that into a custom hook like the one in PlayerContext.tsx
, but using that weirdly didn't have the same effect (read: it didn't have any effect) as just defining the state and context individually for each file it's needed in, like I do it now.
If, by any chance, you have some time and motivation to try this out, I'd be interested if you can get that to work. Of course, that only makes sense if we decide to stick with the context solution.
This repurposes the UI component that is also used on our login page with some adjustments. The mask is shown on the video route, the embed route and also for video blocks in place of the video player. Entering the correct credentials will unlock the video.
"Sticky" meaning that once the credentials are verified, they won't need to be entered again until the user logs out. Anonymous users will need to re-enter the credentials once their browser session ends. This will also make sure that thumbnails in series blocks and search results are shown after a user has been authenticated for a given event.
The ETH sends their series credentials as SHA1 encoded strings including a username and password. This commit adds a config option that causes these credentials to be separated and stored in Tobira's DB when enabled. To authenticate, users will need to enter these credentials, which will then be hashed and checked against the ones we have from the ETH.
d2662a7
to
5f01c3e
Compare
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.
Just did a pass over your latest changes and resolved my previous comments. I still haven't done the "difficult" things I said I will still do.
0ca7595
to
121fd02
Compare
This is not a good solution as it relies on a frontend check. Ideally this would be done in backend. This same applies for thumbnails in search results.
The ETH passwords are inherited from their series, so it is necessary to keep them in sync.
This replaces some relay logic with relay's `fetchQuery` in order to be able to directly react to the query result or failure. I suspect this should also be possible with `loadQuery` and/or `usePreloadedQuery` but I couldn't figure it out. There was sth going on with the previous implementation that was causing the whole page to reload when submitting correct credentials, while entering the wrong credentials caused the loading indicator to spin indefinetely - huh? I don't know what exactly caused this. Anyway, the new solution also makes the whole video route file a little smaller and saves two middle-man components as well as some props. I think it's an overall improvement in terms of readability and maintainability (and fixes the afore mentioned issues).
Authenticating for an event will now also store that event's series id with its credentials. With that, all events of that particular series will be unlocked. This is a feature only used by the ETH, and as such must be enabled via a configuration option.
Before this change, authenticating a video on video pages or in video blocks would not rerender series blocks, i.e. the thumbnails would not reflect the fact that the videos of these blocks were unlocked. This adds a shared state through context so these blocks are now rerendered and correctly show the videos as unlocked.
121fd02
to
8c93f7d
Compare
This adds the necessary backend and frontend implementations to allow event specific authentication as done by the ETH.
For technical information, see commit messages. @LukasKalbertodt to test this, you can use this DB command:
Of course you can use any other event. This will give the event the password user
pass
and the passwordword
.Test here
Closes #1186