Skip to content

Commit

Permalink
Change rDNS check implementation
Browse files Browse the repository at this point in the history
io.github.foo.... -> User must be reachable at https://github.com/foo

page.codeberg.foo... -> User must be reachable at
https://codeberg.org/foo

io.sourceforge.foo... or net.sourceforge.foo -> Project must be
reachable at https://sourceforge.net/projects/foo

io.gitlab.foo, io.frama.foo, org.gnome.gitlab.foo,
org.freedesktop..gitlab.foo -> foo must be a user
(/api/v4/users?username=foo) or a toplevel group (/api/v4/groups/foo)

Anything else: reverse everything except last component and check
website
  • Loading branch information
bbhtt committed Jul 1, 2024
1 parent 2c37e61 commit cf5c1b9
Show file tree
Hide file tree
Showing 24 changed files with 333 additions and 48 deletions.
81 changes: 56 additions & 25 deletions flatpak_builder_lint/checks/appid.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,37 +58,68 @@ def _validate(self, appid: Optional[str], is_extension: bool) -> None:
return
if domainutils.is_app_on_flathub(appid):
return
appid_domain = domainutils.get_domain(appid)
if appid_domain is None:
self.errors.add("appid-domain-not-found")
self.info.add(
f"appid-domain-not-found: Domain for {appid}"
+ " cannot be determined"
if (
appid.startswith(
(
"io.github.",
"page.codeberg.",
"io.sourceforge.",
"net.sourceforge.",
)
)
return
else:
url_http = f"http://{appid_domain}"
url_https = f"https://{appid_domain}"
if appid_domain.endswith(
(".github.io", ".gitlab.io", ".codeberg.io", ".frama.io")
) or appid_domain.startswith("sourceforge.net/projects/"):
if appid_domain.endswith(".gitlab.io"):
if not domainutils.check_url_ok(url_https):
self.errors.add("appid-url-not-reachable")
self.info.add(f"appid-url-not-reachable: Tried {url_https}")
else:
if not domainutils.check_url(url_https):
self.errors.add("appid-url-not-reachable")
self.info.add(f"appid-url-not-reachable: Tried {url_https}")
else:
and domainutils.get_user_url(appid) is not None
):
url = f"https://{domainutils.get_user_url(appid)}"
if not domainutils.check_url(url):
self.errors.add("appid-url-not-reachable")
self.info.add(f"appid-url-not-reachable: Tried {url}")
if appid.startswith(
(
"io.gitlab.",
"io.frama.",
"org.gnome.gitlab.",
"org.freedesktop.gitlab.",
)
):
# Toplevel group names cannot be the same as username
if (
domainutils.get_gitlab_user(appid) is not None
and domainutils.get_gitlab_group(appid) is not None
):
url_user = f"https://{domainutils.get_gitlab_user(appid)}"
url_group = f"https://{domainutils.get_gitlab_group(appid)}"
if not (
domainutils.check_url(url_https)
or domainutils.check_url(url_http)
domainutils.check_gitlab_user(url_user)
or domainutils.check_gitlab_group(url_group)
):
self.errors.add("appid-url-not-reachable")
self.info.add(
f"appid-url-not-reachable: Tried {url_http}, {url_https}"
f"appid-url-not-reachable: Tried {url_user}, {url_group}"
)
if (
not appid.startswith(
(
"io.github.",
"io.frama.",
"page.codeberg.",
"io.sourceforge.",
"net.sourceforge.",
"io.gitlab.",
"org.gnome.gitlab.",
"org.freedesktop.gitlab.",
)
)
and domainutils.get_domain(appid) is not None
):
url_http = f"http://{domainutils.get_domain(appid)}"
url_https = f"https://{domainutils.get_domain(appid)}"
if not (
domainutils.check_url(url_https) or domainutils.check_url(url_http)
):
self.errors.add("appid-url-not-reachable")
self.info.add(
f"appid-url-not-reachable: Tried {url_http}, {url_https}"
)

def check_manifest(self, manifest: dict) -> None:
appid = manifest.get("id")
Expand Down
127 changes: 114 additions & 13 deletions flatpak_builder_lint/domainutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,24 @@ def check_url(url: str) -> bool:
return ret


def check_url_ok(url: str) -> bool:
assert url.endswith(".gitlab.io")
def check_gitlab_user(url: str) -> bool:
assert url.startswith("https://")
ret = False
try:
r = requests.get(url, allow_redirects=False, timeout=10)
if r.status_code == 200:
if len(r.json()) > 0 and isinstance(r.json()[0].get("id"), int):
ret = True
except requests.exceptions.RequestException:
pass
return ret


def check_gitlab_group(url: str) -> bool:
assert url.startswith("https://")
ret = False
try:
r = requests.get(url, allow_redirects=False, timeout=10)
if len(r.json()) > 0 and isinstance(r.json().get("id"), int):
ret = True
except requests.exceptions.RequestException:
pass
Expand All @@ -32,22 +44,111 @@ def demangle(name: str) -> str:
return name


def get_user_url(appid: str) -> str | None:
assert appid.startswith(
("io.github.", "page.codeberg.", "io.sourceforge.", "net.sourceforge.")
)
assert appid.count(".") >= 2

url = None
# None of these have subdomains so all
# we need is the third or fourth component of appid
# to get user url
# as long as the user exists, only they can deploy a pages site
# at user.github.io
third_cpt = demangle(appid.split(".")[2]).lower()

if appid.startswith("io.github."):
url = f"github.com/{third_cpt}"
elif appid.startswith("page.codeberg."):
url = f"codeberg.org/{third_cpt}"
# third component is project name in case of sourceforge
elif appid.startswith(("io.sourceforge.", "net.sourceforge.")):
url = f"sourceforge.net/projects/{third_cpt}"

return url


def get_gitlab_user(appid: str) -> str | None:
assert appid.startswith(
("io.gitlab.", "io.frama.", "org.gnome.gitlab.", "org.freedesktop.gitlab.")
)
assert appid.count(".") >= 2

url = None
third_cpt = demangle(appid.split(".")[2]).lower()
fourth_cpt = demangle(appid.split(".")[3]).lower()

# The third component/fourth component can be the username
# or a toplevel group name. Return the username API url here

# API is used because gitlab returns HTTP 200 on non existent
# user URLs. This is to be passed in check_gitlab_user()

if appid.startswith("io.gitlab."):
url = f"gitlab.com/api/v4/users?username={third_cpt}"
elif appid.startswith("io.frama."):
url = f"framagit.org/api/v4/users?username={third_cpt}"
elif appid.startswith("org.gnome.gitlab."):
url = f"gitlab.gnome.org/api/v4/users?username={fourth_cpt}"
elif appid.startswith("org.freedesktop.gitlab."):
url = f"gitlab.freedesktop.org/api/v4/users?username={fourth_cpt}"

return url


def get_gitlab_group(appid: str) -> str | None:
assert appid.startswith(
("io.gitlab.", "io.frama.", "org.gnome.gitlab.", "org.freedesktop.gitlab.")
)
assert appid.count(".") >= 2

url = None
third_cpt = demangle(appid.split(".")[2]).lower()
fourth_cpt = demangle(appid.split(".")[3]).lower()

# The third component/fourth component can be the toplevel
# group name. Return the groupname API url here

# API is used because gitlab returns HTTP 200 on non existent
# user URLs. This is to be passed in check_gitlab_group()

if appid.startswith("io.gitlab."):
url = f"gitlab.com/api/v4/groups/{third_cpt}"
elif appid.startswith("io.frama."):
url = f"framagit.org/api/v4/groups/{third_cpt}"
elif appid.startswith("org.gnome.gitlab."):
url = f"gitlab.gnome.org/api/v4/groups/{fourth_cpt}"
elif appid.startswith("org.freedesktop.gitlab."):
url = f"gitlab.freedesktop.org/api/v4/groups/{fourth_cpt}"

return url


def get_domain(appid: str) -> str | None:
assert not appid.startswith(
(
"io.github.",
"io.frama.",
"io.gitlab.",
"page.codeberg.",
"io.sourceforge.",
"net.sourceforge.",
"org.gnome.gitlab.",
"org.freedesktop.gitlab.",
)
)
assert appid.count(".") >= 2

domain = None
if appid.startswith("org.gnome."):
if appid.startswith("org.gnome.") and not appid.startswith("org.gnome.gitlab."):
domain = "gnome.org"
elif appid.startswith("org.kde."):
domain = "kde.org"
elif appid.startswith("org.freedesktop."):
elif appid.startswith("org.freedesktop.") and not appid.startswith(
"org.freedesktop.gitlab."
):
domain = "freedesktop.org"
elif appid.startswith(("io.github.", "io.gitlab.", "page.codeberg.", "io.frama.")):
tld = appid.split(".")[0]
demangled = [demangle(i) for i in appid.split(".")[1:3]]
demangled.insert(0, tld)
domain = ".".join(reversed(demangled)).lower()
elif appid.startswith(("io.sourceforge.", "net.sourceforge.")):
proj = demangle(appid.split(".")[2])
domain = f"sourceforge.net/projects/{proj}".lower()
else:
tld = appid.split(".")[0]
demangled = [demangle(i) for i in appid.split(".")[:-1][1:]]
Expand Down
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<component type="desktop-application">
<id>org.freedesktop.gitlab.foo.bar</id>
<id>io.gitlab.wwwwwwwwwwwwwwwwwwwww.bar</id>
<provides>
<id>org.freedesktop.gitlab.foo.bar.desktop</id>
</provides>
<launchable type="desktop-id">org.freedesktop.gitlab.foo.bar.desktop</launchable>
<launchable type="desktop-id">io.gitlab.wwwwwwwwwwwwwwwwwwwww.bar.desktop</launchable>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-2.0+</project_license>
<name>Foo Bar</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Name=Example
GenericName=Example
Comment=Example
Exec=Example %U
Icon=org.freedesktop.gitlab.foo.bar
Icon=io.gitlab.wwwwwwwwwwwwwwwwwwwww.bar
Type=Application
Categories=Network;
Version=1.1
2 changes: 1 addition & 1 deletion tests/builddir/wrong-rdns-appid/metadata
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[Application]
name=io.gitlab.foo.bar
name=io.gitlab.wwwwwwwwwwwwwwwwwwwww.bar
runtime=org.gnome.Platform/x86_64/45
sdk=org.gnome.Sdk/x86_64/45
command=foo
Expand Down
13 changes: 13 additions & 0 deletions tests/manifests/domain_checks/io.frama.wwwwwwwwwwwww.bar.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"app-id": "io.frama.wwwwwwwwwwwww.bar",
"runtime": "foo",
"sdk": "bar",
"command": "foo",
"finish-args": ["--foo=bar"],
"modules": [
{
"name": "module2",
"buildsystem": "autotools"
}
]
}
13 changes: 13 additions & 0 deletions tests/manifests/domain_checks/io.github.wwwwwwwwwwwww.bar.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"app-id": "io.github.wwwwwwwwwwwww.bar",
"runtime": "foo",
"sdk": "bar",
"command": "foo",
"finish-args": ["--foo=bar"],
"modules": [
{
"name": "module2",
"buildsystem": "autotools"
}
]
}
13 changes: 13 additions & 0 deletions tests/manifests/domain_checks/io.github.wwwwwwwwwwwww.foo.bar.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"app-id": "io.github.wwwwwwwwwwwww.foo.bar",
"runtime": "foo",
"sdk": "bar",
"command": "foo",
"finish-args": ["--foo=bar"],
"modules": [
{
"name": "module2",
"buildsystem": "autotools"
}
]
}
13 changes: 13 additions & 0 deletions tests/manifests/domain_checks/io.gitlab.deeplomatics.bar.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"app-id": "io.gitlab.deeplomatics.bar",
"runtime": "foo",
"sdk": "bar",
"command": "foo",
"finish-args": ["--foo=bar"],
"modules": [
{
"name": "module2",
"buildsystem": "autotools"
}
]
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"app-id": "io.gitlab.foo.bar",
"app-id": "io.gitlab.flathub.foo",
"runtime": "foo",
"sdk": "bar",
"command": "foo",
Expand Down
13 changes: 13 additions & 0 deletions tests/manifests/domain_checks/io.gitlab.wwwwwwwwwwwww.bar.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"app-id": "io.gitlab.wwwwwwwwwwwww.bar",
"runtime": "foo",
"sdk": "bar",
"command": "foo",
"finish-args": ["--foo=bar"],
"modules": [
{
"name": "module2",
"buildsystem": "autotools"
}
]
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"app-id": "io.github.ghost.foo.bar",
"app-id": "io.sourceforge.xampp.bar",
"runtime": "foo",
"sdk": "bar",
"command": "foo",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"app-id": "org.freedesktop.gitlab.bbhtt.foo",
"runtime": "foo",
"sdk": "bar",
"command": "foo",
"finish-args": ["--foo=bar"],
"modules": [
{
"name": "module2",
"buildsystem": "autotools"
}
]
}
13 changes: 13 additions & 0 deletions tests/manifests/domain_checks/org.freedesktop.gitlab.mesa.foo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"app-id": "org.freedesktop.gitlab.mesa.foo",
"runtime": "foo",
"sdk": "bar",
"command": "foo",
"finish-args": ["--foo=bar"],
"modules": [
{
"name": "module2",
"buildsystem": "autotools"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"app-id": "org.freedesktop.gitlab.wwwwwwwwwwwww.bar",
"runtime": "foo",
"sdk": "bar",
"command": "foo",
"finish-args": ["--foo=bar"],
"modules": [
{
"name": "module2",
"buildsystem": "autotools"
}
]
}
Loading

0 comments on commit cf5c1b9

Please sign in to comment.