feat: add plasma-face-unlock
This commit is contained in:
commit
f671acc93b
105 files changed
+13862
No files matched your search
@@ -0,0 +1,83 @@
|
||||
# Packaging and releases
|
||||
|
||||
The Makefile installs everything; these only wrap what it produced. That is
|
||||
on purpose: a packaging script that lists the files again is a second
|
||||
description of the layout, and two descriptions drift.
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| `deb/control`, `deb/copyright` | metadata for the Debian binary package |
|
||||
| `rpm/plasma-face-unlock.spec` | the RPM spec |
|
||||
| `aur/PKGBUILD`, `aur/plasma-face-unlock.install` | the AUR package |
|
||||
| `build-deb.sh`, `build-rpm.sh` | build one package into `dist/` |
|
||||
| `check-version.sh` | refuses a tag that disagrees with the Makefile |
|
||||
| `publish-repos.sh` | regenerates the APT and RPM repositories |
|
||||
| `pages/` | the landing page and the `.repo` file served from GitHub Pages |
|
||||
|
||||
Unlike the shell-only LoonixTools, this one is compiled. The packages are per
|
||||
architecture (amd64 and x86_64), and they need the Plasma 6 and Qt 6
|
||||
development packages to build: Debian 13 (trixie) and current Fedora have
|
||||
them. The Debian package's library dependencies are read off the binaries by
|
||||
`dpkg-shlibdeps`; RPM does the same on its own.
|
||||
|
||||
The two networks (YuNet and SFace, from the OpenCV model zoo) are not in the
|
||||
repository. `make models` downloads them and checks them against the
|
||||
checksums in the Makefile. The RPM spec and the PKGBUILD list them as sources
|
||||
of their own, with the same checksums.
|
||||
|
||||
Neither the deb nor the rpm switches anything on at install time. The daemon's
|
||||
socket is enabled by `plasma-face-unlock` the first time somebody turns it on,
|
||||
the agent is a user service each user enables, and the PAM files are only
|
||||
touched when somebody asks for sudo or admin prompts. Removing a package
|
||||
disables the socket.
|
||||
|
||||
## Building one by hand
|
||||
|
||||
```bash
|
||||
packaging/build-deb.sh # in a Debian 13 container, with the -dev packages from release.yml
|
||||
packaging/build-rpm.sh # in a Fedora container, with the -devel packages from the spec
|
||||
```
|
||||
|
||||
Both take the version from `make version` unless one is passed as the first
|
||||
argument.
|
||||
|
||||
## Making a release
|
||||
|
||||
1. Bump `VERSION` in the Makefile. The compiled programs get it from there
|
||||
too (`-DPFU_VERSION`).
|
||||
2. Commit, then `git tag vX.Y.Z && git push --tags`.
|
||||
|
||||
The `release` workflow builds both packages in a Debian and a Fedora container,
|
||||
refuses the tag if it disagrees with the Makefile, attaches the packages to a
|
||||
GitHub release, and adds them to the APT and RPM repositories on the `gh-pages`
|
||||
branch.
|
||||
|
||||
## Trying the release path first
|
||||
|
||||
```bash
|
||||
gh workflow run release.yml -f dry_run=true
|
||||
```
|
||||
|
||||
Builds both packages, builds both repositories with a key generated on the
|
||||
spot, checks the signatures, and installs the packages back out of the
|
||||
repositories. Nothing is pushed and no release is made.
|
||||
|
||||
## Setting up the signing, once
|
||||
|
||||
```bash
|
||||
gpg --batch --passphrase '' --quick-generate-key \
|
||||
'plasma-face-unlock repository <felitendoyt@gmail.com>' rsa4096 sign never
|
||||
|
||||
gpg --armor --export-secret-keys 'plasma-face-unlock repository' \
|
||||
| gh secret set GPG_PRIVATE_KEY
|
||||
```
|
||||
|
||||
Without the secret the workflow still builds both packages and attaches them to
|
||||
the release; it says so in the log and leaves the repositories alone.
|
||||
|
||||
## Pointing Pages at it, once, in this order
|
||||
|
||||
1. Set the secret, above.
|
||||
2. Tag a release. The workflow creates the `gh-pages` branch and fills it.
|
||||
3. *Then* set **Pages** to deploy from a branch and pick `gh-pages` at the
|
||||
root.
|
||||
@@ -0,0 +1,35 @@
|
||||
# Maintainer: Felitendo
|
||||
#
|
||||
# The PKGBUILD for the AUR, kept here next to the code it builds. The copy in
|
||||
# github.com/Felitendo/PKGBUILDS is the one CI bumps and pushes.
|
||||
|
||||
pkgname=plasma-face-unlock
|
||||
pkgver=1.0.0
|
||||
pkgrel=1
|
||||
pkgdesc="Face ID for KDE Plasma: the lock screen, sudo and admin prompts by face, with a photo check"
|
||||
arch=('x86_64' 'aarch64')
|
||||
url="https://github.com/LoonixTools/plasma-face-unlock"
|
||||
license=('GPL-3.0-or-later' 'MIT' 'Apache-2.0')
|
||||
depends=('bash' 'coreutils' 'gawk' 'grep' 'sed' 'gettext' 'systemd' 'systemd-libs' 'pam' 'polkit'
|
||||
'opencv' 'qt6-base' 'qt6-declarative' 'layer-shell-qt' 'kidletime' 'ki18n' 'kscreenlocker')
|
||||
makedepends=('cmake' 'scdoc')
|
||||
install="${pkgname}.install"
|
||||
source=("${pkgname}-${pkgver}.tar.gz::${url}/archive/refs/tags/v${pkgver}.tar.gz"
|
||||
"face_detection_yunet_2023mar.onnx::https://github.com/opencv/opencv_zoo/raw/main/models/face_detection_yunet/face_detection_yunet_2023mar.onnx"
|
||||
"face_recognition_sface_2021dec.onnx::https://github.com/opencv/opencv_zoo/raw/main/models/face_recognition_sface/face_recognition_sface_2021dec.onnx")
|
||||
noextract=('face_detection_yunet_2023mar.onnx' 'face_recognition_sface_2021dec.onnx')
|
||||
sha256sums=('SKIP'
|
||||
'8f2383e4dd3cfbb4553ea8718107fc0423210dc964f9f4280604804ed2552fa4'
|
||||
'0ba9fbfa01b5270c96627c4ef784da859931e02f04419c829e83484087c34e79')
|
||||
|
||||
build() {
|
||||
make -C "${pkgname}-${pkgver}" VERSION="$pkgver"
|
||||
}
|
||||
|
||||
check() {
|
||||
make -C "${pkgname}-${pkgver}" VERSION="$pkgver" test
|
||||
}
|
||||
|
||||
package() {
|
||||
make -C "${pkgname}-${pkgver}" VERSION="$pkgver" MODELS_SRC="$srcdir" DESTDIR="$pkgdir" install
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
post_install() {
|
||||
cat <<'MSG'
|
||||
|
||||
plasma-face-unlock is installed but not active yet.
|
||||
|
||||
plasma-face-unlock interactive menu
|
||||
plasma-face-unlock enable set up your face and turn it on
|
||||
|
||||
Run it as your own user, not with sudo. It asks for your password when it
|
||||
needs to, and sudo and admin prompts stay with the password until you switch
|
||||
them on under Settings.
|
||||
|
||||
MSG
|
||||
}
|
||||
|
||||
pre_remove() {
|
||||
cat <<'MSG'
|
||||
|
||||
Before removing this package, run
|
||||
|
||||
plasma-face-unlock disable
|
||||
|
||||
as each user that turned it on. That takes face unlock back out of sudo and
|
||||
polkit. (Removing it without that is safe too: the PAM line is written so
|
||||
that a missing module is skipped, and sudo keeps asking for the password.)
|
||||
|
||||
MSG
|
||||
systemctl disable --now plasma-face-unlockd.socket plasma-face-unlockd.service >/dev/null 2>&1 || true
|
||||
}
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Builds the binary package for Debian, Ubuntu and their derivatives into
|
||||
# dist/.
|
||||
#
|
||||
# Everything the package contains comes out of `make install`. This only wraps
|
||||
# what that produced, so there is exactly one description of where a file goes
|
||||
# and it is the Makefile.
|
||||
#
|
||||
# Unlike the shell-only tools, this one is compiled, so the package is for one
|
||||
# architecture and its library dependencies are read off the binaries by
|
||||
# dpkg-shlibdeps rather than written down by hand.
|
||||
#
|
||||
# Needs: make, cmake, a C++ compiler, the -dev packages the README lists,
|
||||
# dpkg-dev, msgfmt (gettext), scdoc, curl.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
here="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
version="${1:-$(make -s -C "$here" version)}"
|
||||
name=plasma-face-unlock
|
||||
|
||||
# A package without its man page or its translations is not a package this
|
||||
# should be quietly willing to produce.
|
||||
for tool in msgfmt scdoc dpkg-deb dpkg-shlibdeps cmake; do
|
||||
command -v "$tool" > /dev/null || { echo "$0: $tool is not installed" >&2; exit 1; }
|
||||
done
|
||||
|
||||
root="$(mktemp -d)"
|
||||
work="$(mktemp -d)"
|
||||
trap 'rm -rf -- "$root" "$work"' EXIT
|
||||
|
||||
make -C "$here" models
|
||||
make -C "$here" install \
|
||||
DESTDIR="$root" \
|
||||
PREFIX=/usr \
|
||||
VERSION="$version" \
|
||||
BUILDDIR="$work/build" \
|
||||
SYSTEMUNITDIR=/usr/lib/systemd/system \
|
||||
USERUNITDIR=/usr/lib/systemd/user
|
||||
|
||||
arch="$(dpkg --print-architecture)"
|
||||
|
||||
# The shared libraries the binaries need, as package names.
|
||||
mkdir -p "$work/debian"
|
||||
printf 'Source: %s\n\nPackage: %s\nArchitecture: any\n' "$name" "$name" > "$work/debian/control"
|
||||
mapfile -t elves < <(find "$root" -type f \( -name '*.so' -o -perm -u+x \) -exec sh -c 'head -c4 "$1" | grep -q ELF' _ {} \; -print)
|
||||
depends="$(cd "$work" && dpkg-shlibdeps -O "${elves[@]/#/-e}" 2>/dev/null | sed -n 's/^shlibs:Depends=//p')"
|
||||
[[ -n $depends ]] || { echo "$0: dpkg-shlibdeps found no dependencies" >&2; exit 1; }
|
||||
|
||||
install -d "$root/DEBIAN"
|
||||
sed -e "s|@VERSION@|$version|g" -e "s|@ARCH@|$arch|g" -e "s|@DEPENDS@|$depends|g" \
|
||||
"$here/packaging/deb/control" > "$root/DEBIAN/control"
|
||||
install -Dm644 "$here/packaging/deb/copyright" "$root/usr/share/doc/$name/copyright"
|
||||
|
||||
# The daemon's socket is switched on by the program itself, the first time it
|
||||
# is turned on, so there is nothing to do as root at install time. Removing
|
||||
# the package stops it.
|
||||
cat > "$root/DEBIAN/prerm" <<'SH'
|
||||
#!/bin/sh
|
||||
set -e
|
||||
if [ "$1" = remove ] && [ -d /run/systemd/system ]; then
|
||||
systemctl disable --now plasma-face-unlockd.socket plasma-face-unlockd.service >/dev/null 2>&1 || true
|
||||
fi
|
||||
SH
|
||||
chmod 755 "$root/DEBIAN/prerm"
|
||||
|
||||
( cd "$root" && find . -type f ! -path './DEBIAN/*' -printf '%P\0' \
|
||||
| LC_ALL=C sort -z | xargs -0 md5sum > DEBIAN/md5sums )
|
||||
|
||||
mkdir -p "$here/dist"
|
||||
out="$here/dist/${name}_${version}_${arch}.deb"
|
||||
dpkg-deb --root-owner-group --build "$root" "$out" > /dev/null
|
||||
|
||||
echo "$out"
|
||||
Executable
+43
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Builds the binary package for Fedora into dist/.
|
||||
#
|
||||
# The spec takes the version as a macro rather than carrying one of its own,
|
||||
# for the same reason the Debian control file has a placeholder: the Makefile
|
||||
# is where the version is written down. The two networks are sources of their
|
||||
# own, downloaded (and checked) by `make models` before rpmbuild sees them.
|
||||
#
|
||||
# Needs: rpmbuild, make, cmake, a C++ compiler, the -devel packages the spec
|
||||
# lists, msgfmt (gettext), scdoc, curl, systemd-rpm-macros.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
here="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
version="${1:-$(make -s -C "$here" version)}"
|
||||
name=plasma-face-unlock
|
||||
|
||||
command -v rpmbuild > /dev/null || { echo "$0: rpmbuild is not installed" >&2; exit 1; }
|
||||
|
||||
make -C "$here" models
|
||||
|
||||
top="$(mktemp -d)"
|
||||
trap 'rm -rf -- "$top"' EXIT
|
||||
mkdir -p "$top"/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS}
|
||||
|
||||
# The working tree as it is, not as it was committed: a package built from a
|
||||
# checkout has to contain what is in that checkout.
|
||||
tar czf "$top/SOURCES/$name-$version.tar.gz" \
|
||||
--transform "s,^\\.,$name-$version," \
|
||||
--exclude=./.git --exclude=./dist --exclude=./build --exclude=./models --exclude=./po/'*.mo' \
|
||||
-C "$here" .
|
||||
cp "$here"/models/*.onnx "$top/SOURCES/"
|
||||
|
||||
rpmbuild \
|
||||
--define "_topdir $top" \
|
||||
--define "_version $version" \
|
||||
-bb "$here/packaging/rpm/$name.spec" > /dev/null
|
||||
|
||||
mkdir -p "$here/dist"
|
||||
find "$top/RPMS" -name '*.rpm' -exec cp {} "$here/dist/" \;
|
||||
|
||||
ls "$here/dist/$name-$version"*.rpm
|
||||
Executable
+36
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Refuses a release whose tag and Makefile disagree.
|
||||
#
|
||||
# The version is baked into the program at install time from the Makefile, and
|
||||
# the packages take theirs from the same place. But the tag is what people see
|
||||
# and what the release is named after. A tag that says something else produces
|
||||
# a package called 1.0.4 containing a program that reports 1.0.3, and nothing
|
||||
# would have complained.
|
||||
#
|
||||
# Anything that is not a v-tag (a run started by hand from a branch) is not a
|
||||
# release and has nothing to check.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
here="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
ref="${1:-}"
|
||||
|
||||
case "$ref" in
|
||||
v[0-9]*) ;;
|
||||
*)
|
||||
echo "not a release tag (${ref:-none}), nothing to check against"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
tag_version="${ref#v}"
|
||||
make_version="$(make -s -C "$here" version)"
|
||||
|
||||
if [[ $tag_version != "$make_version" ]]; then
|
||||
echo "tag $ref says $tag_version, the Makefile says $make_version" >&2
|
||||
echo "Bump VERSION in the Makefile to match the tag, or retag." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "$ref matches the Makefile"
|
||||
@@ -0,0 +1,23 @@
|
||||
Package: plasma-face-unlock
|
||||
Version: @VERSION@
|
||||
Section: admin
|
||||
Priority: optional
|
||||
Architecture: @ARCH@
|
||||
Maintainer: Felitendo <felitendoyt@gmail.com>
|
||||
Depends: @DEPENDS@, bash (>= 4.2), coreutils, grep, sed, mawk | gawk, systemd, polkitd | policykit-1, qml6-module-qtquick, qml6-module-qtquick-shapes, qml6-module-qtquick-effects, qml6-module-qtquick-window, qml6-module-qtqml-workerscript
|
||||
Recommends: gettext-base, kscreenlocker
|
||||
Homepage: https://github.com/LoonixTools/plasma-face-unlock
|
||||
Description: face unlock for KDE Plasma
|
||||
Look at the screen and it unlocks, the way a phone does. The lock screen,
|
||||
sudo in a terminal and the admin password prompts of Plasma can take a face
|
||||
instead of a password. A bubble at the top of the screen, above the lock
|
||||
screen too, shows the face being looked for, recognised or refused.
|
||||
.
|
||||
Before a face counts it has to show a sign of life (a blink, or the nose
|
||||
moving the way a real nose does when the head turns), so a photo held up to
|
||||
the camera is not enough. It is a convenience, not a security upgrade: a
|
||||
webcam sees a flat picture, and a video of the person can get through.
|
||||
.
|
||||
Everything runs on the machine. Faces are stored as numbers readable only by
|
||||
root, never as pictures. Run "plasma-face-unlock disable" before removing
|
||||
this package, so that sudo and polkit go back to the password alone.
|
||||
@@ -0,0 +1,49 @@
|
||||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: plasma-face-unlock
|
||||
Source: https://github.com/LoonixTools/plasma-face-unlock
|
||||
|
||||
Files: *
|
||||
Copyright: 2026 Felitendo
|
||||
License: GPL-3+
|
||||
|
||||
Files: usr/share/plasma-face-unlock/models/face_detection_yunet_2023mar.onnx
|
||||
Copyright: 2021-2023 Shiqi Yu, Wei Wu and the YuNet authors
|
||||
License: MIT
|
||||
Comment: https://github.com/opencv/opencv_zoo/tree/main/models/face_detection_yunet
|
||||
|
||||
Files: usr/share/plasma-face-unlock/models/face_recognition_sface_2021dec.onnx
|
||||
Copyright: 2021 Yaoyao Zhong and Weihong Deng
|
||||
License: Apache-2.0
|
||||
Comment: https://github.com/opencv/opencv_zoo/tree/main/models/face_recognition_sface
|
||||
|
||||
License: GPL-3+
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
.
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
.
|
||||
On Debian systems the full text of the GNU General Public License version 3 can
|
||||
be found in /usr/share/common-licenses/GPL-3.
|
||||
|
||||
License: MIT
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
|
||||
License: Apache-2.0
|
||||
On Debian systems the full text of the Apache License 2.0 can be found in
|
||||
/usr/share/common-licenses/Apache-2.0.
|
||||
@@ -0,0 +1,112 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>plasma-face-unlock</title>
|
||||
<style>
|
||||
:root {
|
||||
--bg: #ffffff;
|
||||
--fg: #1b1f23;
|
||||
--muted: #57606a;
|
||||
--rule: #d8dee4;
|
||||
--code-bg: #f6f8fa;
|
||||
--accent: #1793d1;
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root:not([data-theme="light"]) {
|
||||
--bg: #0d1117;
|
||||
--fg: #e6edf3;
|
||||
--muted: #9198a1;
|
||||
--rule: #30363d;
|
||||
--code-bg: #161b22;
|
||||
--accent: #58a6ff;
|
||||
}
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
body {
|
||||
margin: 0 auto;
|
||||
padding: 3rem 1.25rem 5rem;
|
||||
max-width: 46rem;
|
||||
background: var(--bg);
|
||||
color: var(--fg);
|
||||
font: 16px/1.6 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
||||
"Helvetica Neue", Arial, sans-serif;
|
||||
}
|
||||
h1 { font-size: 1.6rem; margin: 0 0 .4rem; }
|
||||
h2 {
|
||||
font-size: 1.05rem; margin: 2.5rem 0 .6rem;
|
||||
padding-bottom: .3rem; border-bottom: 1px solid var(--rule);
|
||||
}
|
||||
p.lead { color: var(--muted); margin: 0 0 2rem; }
|
||||
p { margin: 0 0 1rem; }
|
||||
a { color: var(--accent); }
|
||||
code {
|
||||
background: var(--code-bg); padding: .12em .35em;
|
||||
border-radius: 4px; font-size: .9em;
|
||||
}
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--rule);
|
||||
border-radius: 6px;
|
||||
padding: .9rem 1rem;
|
||||
overflow-x: auto;
|
||||
}
|
||||
pre code { background: none; padding: 0; font-size: .85rem; }
|
||||
footer {
|
||||
margin-top: 3.5rem; padding-top: 1rem;
|
||||
border-top: 1px solid var(--rule);
|
||||
color: var(--muted); font-size: .9rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>plasma-face-unlock</h1>
|
||||
<p class="lead">
|
||||
Face ID for KDE Plasma: look at the screen and it unlocks. The lock screen,
|
||||
sudo and the admin prompts can take a face instead of a password, and a photo
|
||||
of somebody is not enough.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This page is the package repository. Set it up once and every new version
|
||||
arrives with the rest of your system updates. The
|
||||
<a href="https://github.com/LoonixTools/plasma-face-unlock">source and the
|
||||
documentation</a> are on GitHub.
|
||||
</p>
|
||||
|
||||
<h2>Debian 13 or newer, Kubuntu 25.04 or newer</h2>
|
||||
<pre><code>sudo install -d -m 0755 /etc/apt/keyrings
|
||||
curl -fsSL @BASEURL@/KEY.gpg \
|
||||
| sudo gpg --dearmor -o /etc/apt/keyrings/plasma-face-unlock.gpg
|
||||
echo "deb [signed-by=/etc/apt/keyrings/plasma-face-unlock.gpg] @BASEURL@/deb ./" \
|
||||
| sudo tee /etc/apt/sources.list.d/plasma-face-unlock.list
|
||||
sudo apt update
|
||||
sudo apt install plasma-face-unlock</code></pre>
|
||||
|
||||
<h2>Fedora (KDE Plasma)</h2>
|
||||
<pre><code>sudo curl -fsSL -o /etc/yum.repos.d/plasma-face-unlock.repo \
|
||||
@BASEURL@/plasma-face-unlock.repo
|
||||
sudo dnf install plasma-face-unlock</code></pre>
|
||||
|
||||
<h2>Arch, CachyOS, EndeavourOS, Manjaro</h2>
|
||||
<pre><code>paru -S plasma-face-unlock</code></pre>
|
||||
|
||||
<h2>Then, once</h2>
|
||||
<pre><code>plasma-face-unlock</code></pre>
|
||||
<p>
|
||||
Press 1. It sets up your face (look at the camera, move your head in a
|
||||
circle) and turns face unlock on. sudo and the admin prompts are off until
|
||||
you switch them on under Settings. Run <code>plasma-face-unlock disable</code>
|
||||
before removing the package: it takes face unlock back out of sudo and
|
||||
polkit.
|
||||
</p>
|
||||
|
||||
<footer>
|
||||
GPL-3.0-or-later. Packages are signed; the public key is
|
||||
<a href="@BASEURL@/KEY.gpg">KEY.gpg</a>.
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
[plasma-face-unlock]
|
||||
name=plasma-face-unlock
|
||||
baseurl=@BASEURL@/rpm
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
repo_gpgcheck=1
|
||||
gpgkey=@BASEURL@/KEY.gpg
|
||||
Executable
+88
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Puts the packages that were just built into the APT and RPM repositories on
|
||||
# the gh-pages branch, and regenerates the indexes over everything that is
|
||||
# there.
|
||||
#
|
||||
# Old versions are kept rather than replaced. An index built over all of them
|
||||
# is what lets somebody pin a version or go back to one, and it costs a few
|
||||
# hundred kilobytes.
|
||||
#
|
||||
# Usage: publish-repos.sh <gh-pages checkout> <directory of new packages>
|
||||
#
|
||||
# Needs: dpkg-dev, apt-utils, createrepo-c, gpg, and a secret key already
|
||||
# imported. Its id is taken from the keyring.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
pages="$(cd -- "$1" && pwd)"
|
||||
incoming="$(cd -- "$2" && pwd)"
|
||||
here="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
|
||||
base_url="${PFU_REPO_URL:-https://loonixtools.github.io/plasma-face-unlock}"
|
||||
|
||||
keyid="$(gpg --list-secret-keys --with-colons | awk -F: '/^sec:/ { print $5; exit }')"
|
||||
[[ -n $keyid ]] || { echo "$0: no secret key in the keyring" >&2; exit 1; }
|
||||
|
||||
mkdir -p "$pages/deb" "$pages/rpm"
|
||||
cp -- "$incoming"/*.deb "$pages/deb/"
|
||||
cp -- "$incoming"/*.rpm "$pages/rpm/"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# APT
|
||||
# ---------------------------------------------------------------------------
|
||||
# A flat repository: the packages and their index sit in one directory and the
|
||||
# sources line ends in "./". There is one distribution here and it is the same
|
||||
# package for all of them, so the suite and component machinery of a pool
|
||||
# layout would describe nothing.
|
||||
(
|
||||
cd "$pages/deb"
|
||||
|
||||
# The old index must be gone before the new one is written: apt-ftparchive
|
||||
# hashes every file in the directory, and a Release that hashes the
|
||||
# previous Release is a Release that cannot be verified.
|
||||
rm -f Packages Packages.gz Release Release.gpg InRelease
|
||||
|
||||
dpkg-scanpackages --multiversion . > Packages
|
||||
gzip -9kf Packages
|
||||
|
||||
apt-ftparchive \
|
||||
-o APT::FTPArchive::Release::Origin=plasma-face-unlock \
|
||||
-o APT::FTPArchive::Release::Label=plasma-face-unlock \
|
||||
-o APT::FTPArchive::Release::Suite=stable \
|
||||
-o APT::FTPArchive::Release::Codename=stable \
|
||||
-o APT::FTPArchive::Release::Architectures=amd64 \
|
||||
-o APT::FTPArchive::Release::Components=main \
|
||||
release . > Release
|
||||
|
||||
# Both signatures: InRelease is what current apt fetches, Release.gpg is
|
||||
# what an older one falls back to.
|
||||
gpg --batch --yes --local-user "$keyid" --clearsign --output InRelease Release
|
||||
gpg --batch --yes --local-user "$keyid" --detach-sign --armor --output Release.gpg Release
|
||||
)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# RPM
|
||||
# ---------------------------------------------------------------------------
|
||||
(
|
||||
cd "$pages/rpm"
|
||||
createrepo_c --quiet --update .
|
||||
rm -f repodata/repomd.xml.asc
|
||||
gpg --batch --yes --local-user "$keyid" --detach-sign --armor repodata/repomd.xml
|
||||
)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# The key and the landing page
|
||||
# ---------------------------------------------------------------------------
|
||||
gpg --armor --export "$keyid" > "$pages/KEY.gpg"
|
||||
|
||||
sed "s|@BASEURL@|$base_url|g" "$here/packaging/pages/index.html" > "$pages/index.html"
|
||||
sed "s|@BASEURL@|$base_url|g" "$here/packaging/pages/plasma-face-unlock.repo" \
|
||||
> "$pages/plasma-face-unlock.repo"
|
||||
|
||||
# Pages would otherwise hand the whole directory to Jekyll, which drops every
|
||||
# file whose name starts with an underscore and can rewrite the rest.
|
||||
touch "$pages/.nojekyll"
|
||||
|
||||
echo "signed with $keyid"
|
||||
ls -1 "$pages/deb" "$pages/rpm"
|
||||
@@ -0,0 +1,101 @@
|
||||
# Built with `packaging/build-rpm.sh`, which passes the version in rather than
|
||||
# editing this file: the Makefile is where the version is written down.
|
||||
%global upstream_version %{?_version}%{!?_version:1.0.0}
|
||||
|
||||
Name: plasma-face-unlock
|
||||
Version: %{upstream_version}
|
||||
Release: 1%{?dist}
|
||||
Summary: Face unlock for KDE Plasma
|
||||
|
||||
# The program is GPL; the two networks it ships are MIT (YuNet) and
|
||||
# Apache-2.0 (SFace).
|
||||
License: GPL-3.0-or-later AND MIT AND Apache-2.0
|
||||
URL: https://github.com/LoonixTools/plasma-face-unlock
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
Source1: https://github.com/opencv/opencv_zoo/raw/main/models/face_detection_yunet/face_detection_yunet_2023mar.onnx
|
||||
Source2: https://github.com/opencv/opencv_zoo/raw/main/models/face_recognition_sface/face_recognition_sface_2021dec.onnx
|
||||
|
||||
BuildRequires: cmake
|
||||
BuildRequires: gcc-c++
|
||||
BuildRequires: make
|
||||
BuildRequires: gettext
|
||||
BuildRequires: scdoc
|
||||
BuildRequires: systemd-rpm-macros
|
||||
BuildRequires: pkgconfig(systemd)
|
||||
BuildRequires: pkgconfig(libsystemd)
|
||||
BuildRequires: pam-devel
|
||||
BuildRequires: opencv-devel
|
||||
BuildRequires: cmake(Qt6Core)
|
||||
BuildRequires: cmake(Qt6DBus)
|
||||
BuildRequires: cmake(Qt6Network)
|
||||
BuildRequires: cmake(Qt6Gui)
|
||||
BuildRequires: cmake(Qt6Quick)
|
||||
BuildRequires: cmake(Qt6WaylandClient)
|
||||
BuildRequires: qt6-qtbase-private-devel
|
||||
BuildRequires: qt6-qtwayland-devel
|
||||
BuildRequires: cmake(LayerShellQt)
|
||||
BuildRequires: cmake(KF6IdleTime)
|
||||
BuildRequires: cmake(KF6I18n)
|
||||
|
||||
Requires: bash >= 4.2
|
||||
Requires: coreutils
|
||||
Requires: gawk
|
||||
Requires: grep
|
||||
Requires: sed
|
||||
Requires: polkit
|
||||
Requires: systemd
|
||||
Requires: qt6-qtdeclarative
|
||||
Recommends: /usr/bin/gettext
|
||||
Recommends: kscreenlocker
|
||||
|
||||
%description
|
||||
Look at the screen and it unlocks, the way a phone does. The lock screen, sudo
|
||||
in a terminal and the admin password prompts of Plasma can take a face instead
|
||||
of a password. A bubble at the top of the screen, above the lock screen too,
|
||||
shows the face being looked for, recognised or refused.
|
||||
|
||||
Before a face counts it has to show a sign of life (a blink, or the nose moving
|
||||
the way a real nose does when the head turns), so a photo held up to the camera
|
||||
is not enough. It is a convenience, not a security upgrade: a webcam sees a
|
||||
flat picture, and a video of the person can get through.
|
||||
|
||||
Run "plasma-face-unlock disable" before removing this package, so that sudo
|
||||
and polkit go back to the password alone.
|
||||
|
||||
%prep
|
||||
%autosetup -n %{name}-%{version}
|
||||
mkdir -p models
|
||||
cp %{SOURCE1} %{SOURCE2} models/
|
||||
|
||||
%build
|
||||
%set_build_flags
|
||||
make VERSION=%{upstream_version} PREFIX=%{_prefix} PAMDIR=%{_libdir}/security
|
||||
|
||||
%install
|
||||
make install DESTDIR=%{buildroot} PREFIX=%{_prefix} VERSION=%{upstream_version} \
|
||||
PAMDIR=%{_libdir}/security SYSTEMUNITDIR=%{_unitdir} USERUNITDIR=%{_userunitdir}
|
||||
|
||||
%find_lang %{name}
|
||||
|
||||
%preun
|
||||
%systemd_preun plasma-face-unlockd.socket plasma-face-unlockd.service
|
||||
|
||||
%postun
|
||||
%systemd_postun plasma-face-unlockd.socket plasma-face-unlockd.service
|
||||
|
||||
%files -f %{name}.lang
|
||||
%license LICENSE
|
||||
%doc %{_datadir}/doc/%{name}/README.md
|
||||
%{_bindir}/%{name}
|
||||
%{_prefix}/lib/%{name}/
|
||||
%{_datadir}/%{name}/
|
||||
%{_libdir}/security/pam_plasma_face_unlock.so
|
||||
%{_unitdir}/plasma-face-unlockd.socket
|
||||
%{_unitdir}/plasma-face-unlockd.service
|
||||
%{_userunitdir}/plasma-face-unlock-agent.service
|
||||
%{_datadir}/applications/io.github.loonixtools.plasma-face-unlock-agent.desktop
|
||||
%{_datadir}/polkit-1/actions/io.github.loonixtools.plasma-face-unlock.policy
|
||||
%{_datadir}/icons/hicolor/scalable/apps/plasma-face-unlock.svg
|
||||
%{_mandir}/man1/%{name}.1*
|
||||
|
||||
%changelog
|
||||
Reference in new issue
Block a user