Skip to content

Commit 36795f2

Browse files
javanlacerdadi
andauthored
Verified project links for project details. (#15862)
* adding source as project link verified Signed-off-by: Javan lacerda <[email protected]> * removing Project links from unverified section when its verified Signed-off-by: Javan lacerda <[email protected]> * create query for getting project trusted published files Signed-off-by: Javan lacerda <[email protected]> * update query Signed-off-by: Javan lacerda <[email protected]> * make translations, update query Signed-off-by: Javan lacerda <[email protected]> * using ilike for filter instead contains Signed-off-by: Javan lacerda <[email protected]> * creating verified and unverified lists Signed-off-by: Javan lacerda <[email protected]> * paarametrize tests Signed-off-by: Javan lacerda <[email protected]> * dedup uri checking Signed-off-by: Javan lacerda <[email protected]> * make translations Signed-off-by: Javan lacerda <[email protected]> * fix lint Signed-off-by: Javan lacerda <[email protected]> * Update warehouse/packaging/models.py * Move the links up in the sidebar * Update test parameters * Make a failing test * Handle trailing slashes * Include 'Issues' as well * Update translations --------- Signed-off-by: Javan lacerda <[email protected]> Co-authored-by: Dustin Ingram <[email protected]>
1 parent 594fd2e commit 36795f2

File tree

4 files changed

+94
-29
lines changed

4 files changed

+94
-29
lines changed

tests/unit/packaging/test_models.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,33 @@ def test_trusted_published_all(self, db_session):
758758

759759
assert release.trusted_published
760760

761+
@pytest.mark.parametrize(
762+
"url, publisher_url, expected",
763+
[
764+
("xpto.com", "https://pub/url/", False), # Totally different
765+
("https://pub/", "https://pub/url/", False), # Missing parts
766+
("https://pub/url/", "https://pub/url/", True), # Exactly the same
767+
("https://pub/url/blah.md", "https://pub/url/", True), # Additonal parts
768+
("https://pub/url", "https://pub/url/", True), # Missing trailing slash
769+
("https://pub/url/", "https://pub/url", True), # Extratrailing slash
770+
],
771+
)
772+
def test_is_url_verified(self, db_session, url, publisher_url, expected):
773+
project = DBProjectFactory.create()
774+
release = DBReleaseFactory.create(project=project)
775+
release_file = DBFileFactory.create(
776+
release=release,
777+
filename=f"{release.project.name}-{release.version}.tar.gz",
778+
python_version="source",
779+
)
780+
DBFileEventFactory.create(
781+
source=release_file,
782+
tag="fake:event",
783+
additional={"publisher_url": publisher_url},
784+
)
785+
786+
assert project.is_verified_url(url) is expected
787+
761788
def test_trusted_published_mixed(self, db_session):
762789
release = DBReleaseFactory.create()
763790
rfile_1 = DBFileFactory.create(

warehouse/locale/messages.pot

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -776,7 +776,7 @@ msgstr ""
776776
#: warehouse/templates/includes/accounts/profile-actions.html:30
777777
#: warehouse/templates/includes/accounts/profile-callout.html:18
778778
#: warehouse/templates/includes/hash-modal.html:23
779-
#: warehouse/templates/includes/packaging/project-data.html:106
779+
#: warehouse/templates/includes/packaging/project-data.html:125
780780
#: warehouse/templates/index.html:100 warehouse/templates/index.html:104
781781
#: warehouse/templates/manage/account.html:228
782782
#: warehouse/templates/manage/account.html:234
@@ -3077,47 +3077,48 @@ msgstr ""
30773077
msgid "Members"
30783078
msgstr ""
30793079

3080-
#: warehouse/templates/includes/packaging/project-data.html:16
3080+
#: warehouse/templates/includes/packaging/project-data.html:27
30813081
msgid "Verified details"
30823082
msgstr ""
30833083

3084-
#: warehouse/templates/includes/packaging/project-data.html:31
3084+
#: warehouse/templates/includes/packaging/project-data.html:30
3085+
#: warehouse/templates/includes/packaging/project-data.html:73
3086+
msgid "Project links"
3087+
msgstr ""
3088+
3089+
#: warehouse/templates/includes/packaging/project-data.html:52
30853090
msgid "Maintainers"
30863091
msgstr ""
30873092

3088-
#: warehouse/templates/includes/packaging/project-data.html:33
3093+
#: warehouse/templates/includes/packaging/project-data.html:54
30893094
msgid "Avatar for {username} from gravatar.com"
30903095
msgstr ""
30913096

3092-
#: warehouse/templates/includes/packaging/project-data.html:49
3097+
#: warehouse/templates/includes/packaging/project-data.html:70
30933098
msgid "Unverified details"
30943099
msgstr ""
30953100

3096-
#: warehouse/templates/includes/packaging/project-data.html:52
3097-
msgid "Project links"
3098-
msgstr ""
3099-
3100-
#: warehouse/templates/includes/packaging/project-data.html:66
3101+
#: warehouse/templates/includes/packaging/project-data.html:85
31013102
msgid "GitHub Statistics"
31023103
msgstr ""
31033104

3104-
#: warehouse/templates/includes/packaging/project-data.html:74
3105+
#: warehouse/templates/includes/packaging/project-data.html:93
31053106
msgid "Stars:"
31063107
msgstr ""
31073108

3108-
#: warehouse/templates/includes/packaging/project-data.html:82
3109+
#: warehouse/templates/includes/packaging/project-data.html:101
31093110
msgid "Forks:"
31103111
msgstr ""
31113112

3112-
#: warehouse/templates/includes/packaging/project-data.html:90
3113+
#: warehouse/templates/includes/packaging/project-data.html:109
31133114
msgid "Open issues:"
31143115
msgstr ""
31153116

3116-
#: warehouse/templates/includes/packaging/project-data.html:98
3117+
#: warehouse/templates/includes/packaging/project-data.html:117
31173118
msgid "Open PRs:"
31183119
msgstr ""
31193120

3120-
#: warehouse/templates/includes/packaging/project-data.html:106
3121+
#: warehouse/templates/includes/packaging/project-data.html:125
31213122
#, python-format
31223123
msgid ""
31233124
"View statistics for this project via <a href=\"%(libs_io_href)s\" "
@@ -3126,38 +3127,38 @@ msgid ""
31263127
"rel=\"noopener\">our public dataset on Google BigQuery</a>"
31273128
msgstr ""
31283129

3129-
#: warehouse/templates/includes/packaging/project-data.html:113
3130+
#: warehouse/templates/includes/packaging/project-data.html:132
31303131
msgid "Meta"
31313132
msgstr ""
31323133

3133-
#: warehouse/templates/includes/packaging/project-data.html:115
3134+
#: warehouse/templates/includes/packaging/project-data.html:134
31343135
msgid "License:"
31353136
msgstr ""
31363137

3137-
#: warehouse/templates/includes/packaging/project-data.html:118
3138-
#: warehouse/templates/includes/packaging/project-data.html:120
3138+
#: warehouse/templates/includes/packaging/project-data.html:137
3139+
#: warehouse/templates/includes/packaging/project-data.html:139
31393140
msgid "Author:"
31403141
msgstr ""
31413142

3142-
#: warehouse/templates/includes/packaging/project-data.html:123
3143-
#: warehouse/templates/includes/packaging/project-data.html:125
3143+
#: warehouse/templates/includes/packaging/project-data.html:142
3144+
#: warehouse/templates/includes/packaging/project-data.html:144
31443145
#: warehouse/templates/pages/help.html:610
31453146
msgid "Maintainer:"
31463147
msgstr ""
31473148

3148-
#: warehouse/templates/includes/packaging/project-data.html:130
3149+
#: warehouse/templates/includes/packaging/project-data.html:149
31493150
msgid "Tags"
31503151
msgstr ""
31513152

3152-
#: warehouse/templates/includes/packaging/project-data.html:140
3153+
#: warehouse/templates/includes/packaging/project-data.html:159
31533154
msgid "Requires:"
31543155
msgstr ""
31553156

3156-
#: warehouse/templates/includes/packaging/project-data.html:145
3157+
#: warehouse/templates/includes/packaging/project-data.html:164
31573158
msgid "Provides-Extra:"
31583159
msgstr ""
31593160

3160-
#: warehouse/templates/includes/packaging/project-data.html:153
3161+
#: warehouse/templates/includes/packaging/project-data.html:172
31613162
#: warehouse/templates/pages/classifiers.html:16
31623163
#: warehouse/templates/pages/classifiers.html:21
31633164
#: warehouse/templates/pages/sitemap.html:39

warehouse/packaging/models.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
Text,
3434
UniqueConstraint,
3535
func,
36+
literal,
3637
or_,
3738
orm,
3839
sql,
@@ -399,6 +400,23 @@ def latest_version(self):
399400
.first()
400401
)
401402

403+
def is_verified_url(self, url):
404+
url = url.rstrip("/") + "/" # Ensure a single trailing slash
405+
return (
406+
orm.object_session(self)
407+
.query(File.Event)
408+
.join(File)
409+
.join(Release)
410+
.join(Project)
411+
.filter(Project.id == self.id)
412+
.filter(
413+
literal(url).ilike(
414+
File.Event.additional.op("->>")("publisher_url") + "%"
415+
)
416+
)
417+
.scalar()
418+
) is not None
419+
402420

403421
class DependencyKind(enum.IntEnum):
404422
requires = 1

warehouse/templates/includes/packaging/project-data.html

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,30 @@
1212
# limitations under the License.
1313
-#}
1414

15+
{% set verified_urls, unverified_urls = [],[] %}
16+
{% for name, url in release.urls.items() %}
17+
{% if is_valid_uri(url) %}
18+
{% if name in ["Source", "Homepage", "Issues"] and project.is_verified_url(url) %}
19+
{{ verified_urls.append((name, url)) }}
20+
{% else %}
21+
{{ unverified_urls.append((name, url)) }}
22+
{% endif %}
23+
{% endif %}
24+
{% endfor %}
25+
1526
<div class="sidebar-section verified">
1627
<h3 class="sidebar-section__title">{% trans %}Verified details{% endtrans %}</h3>
1728
<small><i>These details have been verified by PyPI</i></small>
29+
{% if verified_urls.values() %}
30+
<h6>{% trans %}Project links{% endtrans %}</h6>
31+
{% for name, url in verified_urls %}
32+
<li>
33+
<a class="vertical-tabs__tab vertical-tabs__tab--with-icon vertical-tabs__tab--condensed" href="{{ url }}" rel="nofollow">
34+
{{ url_icon(name, url) }}{{ name }} <i class="fa fa-circle-check check"></i>
35+
</a>
36+
</li>
37+
{% endfor %}
38+
{% endif %}
1839
{% if project.organization %}
1940
<h6>Owner</h6>
2041
<span class="sidebar-section__maintainer">
@@ -48,17 +69,15 @@ <h6>{% trans %}Maintainers{% endtrans %}</h6>
4869
<div class="sidebar-section verified">
4970
<h3 class="sidebar-section__title">{% trans %}Unverified details{% endtrans %}</h3>
5071
<small><i>These details have <b>not</b> been verified by PyPI</i></small>
51-
{% if release.urls.values() | contains_valid_uris %}
72+
{% if unverified_urls.values() %}
5273
<h6>{% trans %}Project links{% endtrans %}</h6>
5374
<ul class="vertical-tabs__list">
54-
{% for name, url in release.urls.items() %}
55-
{% if is_valid_uri(url) %}
75+
{% for name, url in unverified_urls %}
5676
<li>
5777
<a class="vertical-tabs__tab vertical-tabs__tab--with-icon vertical-tabs__tab--condensed" href="{{ url }}" rel="nofollow">
5878
{{ url_icon(name, url) }}{{ name }}
5979
</a>
6080
</li>
61-
{% endif %}
6281
{% endfor %}
6382
</ul>
6483
{% endif %}

0 commit comments

Comments
 (0)