feat: add plasma-face-unlock

This commit is contained in:
Felitendo committed 2026-09-22 19:39:04 +02:00
commit f671acc93b
105 files changed
+13862

No files matched your search

+83
View File
@@ -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.
+35
View File
@@ -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
}
+29
View File
@@ -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
}
+75
View File
@@ -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"
+43
View File
@@ -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
+36
View File
@@ -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"
+23
View File
@@ -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.
+49
View File
@@ -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.
+112
View File
@@ -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>
+7
View File
@@ -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
+88
View File
@@ -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"
+101
View File
@@ -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