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

Project RSS feed #1158

Merged
merged 1 commit into from
Jul 28, 2023
Merged

Project RSS feed #1158

merged 1 commit into from
Jul 28, 2023

Conversation

azmeuk
Copy link
Contributor

@azmeuk azmeuk commented Apr 22, 2023

Partially implements #1130, possibly etags and if-modified-since headers are missing, but let's discuss this in #1130

This patch generates a feed for each project, with a dynamic secret part in the URL based on the existing Project.generate_token method. The generated feed passes the w3c validation

<title> and <description> can probably different, but the main data is here. Let me know what you prefer. Also, the content is simple enough so it does not need to be localized. If more information is needed and the feed content does need to be localized, maybe a lang variable can be added to the feed URL.

Maybe it worth adding an icon somewhere? Near the Invite button?
A firefox extension like awesome-rss automatically detects the feed on a project page, so I can live without it.

@azmeuk azmeuk mentioned this pull request Apr 22, 2023
@Glandos
Copy link
Member

Glandos commented May 19, 2023

As mentioned:

However in order to be able to do this, this would be needed to save the last update datetime for projects. This date would be updated at each bill addition/edition, and would be used to generate the ETag and Last-Modified headers.

We are using SQLAlchemy-continuum, so I guess that the last transaction is already accessible. But I don't have time to investigate it right now, it's just an idea.

@azmeuk
Copy link
Contributor Author

azmeuk commented May 19, 2023

I can look at this in another PR once this one is merged if it OK with you.

@azmeuk
Copy link
Contributor Author

azmeuk commented Jul 18, 2023

@Glandos any chance you might have some time to review this soon 🙏 ?
Do you have any questions about the implementation? If that can help, we can discuss on irc/matrix/whatever or have a call.

Copy link
Member

@almet almet left a comment

Choose a reason for hiding this comment

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

Thanks for working on this. It's working the right way to me, as the generated URLs will be able to only access the RSS endpoint.

Before merging, we should IMO decide if we want to integrate etags and if-modified-since, so that what we have in the main branch is feature-complete.

I advocate for the integration of these two =)

xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel>
<title>{{ g.project.name }}</title>
Copy link
Member

Choose a reason for hiding this comment

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

Maybe add "I Hate Money — " as a prefix here maybe, to make it obvious in the feed reader?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure this is needed. Most readers display the channel name somewhere. Often you can also click select channel to only see the items for that specific channel. Displaying I Hate Money feels redundant to me.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure I get it. Are you saying the channel name isn't coming from the <title>tag? If you only have the project name, how do you know it's coming from this software?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ahh my bad. I though we were talking about the item title, and not the channel title. It makes sense, I fixed that.

ihatemoney/templates/project_feed.xml Outdated Show resolved Hide resolved
ihatemoney/tests/budget_test.py Show resolved Hide resolved
ihatemoney/models.py Show resolved Hide resolved
@almet
Copy link
Member

almet commented Jul 24, 2023

Maybe it worth adding an icon somewhere? Near the Invite button?

What about adding a link and a button in the settings of the project?

@almet almet self-requested a review July 24, 2023 19:12
@azmeuk
Copy link
Contributor Author

azmeuk commented Jul 24, 2023

What about adding a link and a button in the settings of the project?

I added a RSS button next to the CSS and JSON. Not sure about the icon, I used a picture that was already there.

Copy link
Member

@almet almet 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 to me, I added a few other comments after a second pass. Hope you don't mind too much.

Thanks again for the work on this. I'm curious what other people think about etags and so on.

MANIFEST.in Show resolved Hide resolved
xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel>
<title>{{ g.project.name }}</title>
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure I get it. Are you saying the channel name isn't coming from the <title>tag? If you only have the project name, how do you know it's coming from this software?

>
<channel>
<title>raclette</title>
<description>A simple shared budget manager web application</description>
Copy link
Member

Choose a reason for hiding this comment

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

Well, actually it feels odd to me. You need to state that it's a feed with the latest bills from this project, maybe?

ihatemoney/tests/budget_test.py Show resolved Hide resolved
@azmeuk
Copy link
Contributor Author

azmeuk commented Jul 25, 2023

Looks good to me, I added a few other comments after a second pass. Hope you don't mind too much.

Not at all, I understand what maintainership is and why you may be careful.

I'm curious what other people think about etags and so on.

I'll look at this soon.

@azmeuk
Copy link
Contributor Author

azmeuk commented Jul 25, 2023

@almet to be able to return a 304 HTTP code, with etags/if-modified-since, we need to keep track of the last update datetime for a given project. I suppose this would mean to add a new column in the model, and update this whenever a bill is added/edited/deleted in the project.

Are you OK with that?

@almet
Copy link
Member

almet commented Jul 25, 2023

@almet to be able to return a 304 HTTP code, with etags/if-modified-since, we need to keep track of the last update datetime for a given project. I suppose this would mean to add a new column in the model, and update this whenever a bill is added/edited/deleted in the project.

Are you OK with that?

As @Glandos noted earlier, we're using SQLAlchemy-continuum to version the changes, which should make things easier for us.

It took me some time to find out that the Transaction class has a issued_at property which might be useful for us here.

I'm not sure if we have to chose between ETag/If-None-Match and if-modified-since, or if we should do both of them? (seems redundant, but I guess it depends what's implemented in the clients?).

I advocate for using the easier one (unless there is something I don't get), which in this case seems to be if-modified-since.

@azmeuk
Copy link
Contributor Author

azmeuk commented Jul 25, 2023

Ok thank you for the tips I will look at that. I think both headers can be implemented at a cheap cost.

@azmeuk
Copy link
Contributor Author

azmeuk commented Jul 25, 2023

I just force-pushed the branch with the integration of the headers.

I added pytest-libfaketime as a dev dependency to mock datetimes. I chose this instead of freezegun because, as freezegun is pure python it would not correctly mock sqlalchemy datetimes, but libfaketime works on a lower level and is able to mock sqlalchemy issue_at attributes (at least without a heavy setup).
libfaketime does not look very active, but this is because it is mainly stable. I maintain the pytest plugin, and in the past the maintainer was welcoming to contributions, so that wouldn't worry me.

I use continuum to find the last datetime edition for a project, and handle if-modified-since, and then I use this date to build a etag to manage if-none-match.

I could not track bills edition that way though, but addition/deletion works fine.

@azmeuk
Copy link
Contributor Author

azmeuk commented Jul 26, 2023

I just realized that I forgot to send the etag and last-modified headers back. I need to fix that.

@azmeuk
Copy link
Contributor Author

azmeuk commented Jul 27, 2023

This is better now.

tox.ini Show resolved Hide resolved
Copy link
Collaborator

@zorun zorun left a comment

Choose a reason for hiding this comment

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

I really like the approach, thanks a lot for working on this!

I left some comments, I hope you don't mind adding a few more tests ;)

ihatemoney/web.py Show resolved Hide resolved
ihatemoney/web.py Show resolved Hide resolved
ihatemoney/templates/edit_project.html Outdated Show resolved Hide resolved
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add a test that checks that we can't access another project with a "feed" token. Our first and only CVE was about unauthorized access by tweaking the project ID, so we definitely want to check that we don't introduce a similar issue for this new route (even if it's read-only).

Two cases are interesting: another project with the same private code, and another project with a different private code. Both should not allow access.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I was thinking of accessing the RSS feed of another project with the RSS token. Your new tests try to use the RSS token as an invite token, which is already well covered by test_invalid_invite_link_with_feed_token.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok that makes more sense 😅
I'll fix that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is fixed 👍

ihatemoney/models.py Show resolved Hide resolved
@azmeuk azmeuk force-pushed the issue-1130-rss-feed branch 3 times, most recently from 7bd8a49 to 641a456 Compare July 28, 2023 11:57
@azmeuk azmeuk requested a review from zorun July 28, 2023 12:00
Copy link
Member

@almet almet left a comment

Choose a reason for hiding this comment

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

LGTM!

ihatemoney/templates/edit_project.html Outdated Show resolved Hide resolved
@zorun
Copy link
Collaborator

zorun commented Jul 28, 2023

Thanks for the changes, I still have a change request on the tests (testing we can't access other project's RSS feed), otherwise the rest looks good to me!

Copy link
Collaborator

@zorun zorun left a comment

Choose a reason for hiding this comment

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

Nice work!

@zorun zorun merged commit 8d4584d into spiral-project:master Jul 28, 2023
15 checks passed
@azmeuk azmeuk deleted the issue-1130-rss-feed branch July 28, 2023 13:26
@almet
Copy link
Member

almet commented Jul 28, 2023

Thanks again for the work on this. Yay!

@zorun
Copy link
Collaborator

zorun commented Jul 29, 2023

@azmeuk we will do a release soon with this change (I just plan to finish the work on #1204 before that)

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.

4 participants