bookmark_borderHorde’s new Two-Factor API

New Horde 6 feature: The horde/horde base app’s next release supports two factor logins.
Dmitry Petrov is working to release a new One-Time Password module which integrates with this new API.

Seemless integration for One Time Passwords.

Several years ago I did some downstream development for a customer. They wanted to use One Time Passwords (OTP) in their custom horde application as a way to offer Two-Factor Authentication (2FA). It worked well for the specific use case but it required patching the base Horde system or substantial reconfiguration, basically delegating authentication to this app. Unfortunately, this had several downsides.

Recently I was approached by Dmitry Petrov. He has built his own OTP solution for horde and offered to upstream his module. Time was ripe to finally provide an interface for Two Factor Authentication.

When horde detects the secondfactor/isEnabled API, it adds an additional field to the default login screen.

This also works in smartmobile view. The second factor is not required when connecting to JSON-RPC or CalDAV endpoints. It is only checked for UI logins. Support is currently restricted to the bare minimum. OTP authentication can be opt-in or mandatory – The horde base app does not know this. A future version may force the user into an OTP setup screen after login if no OTP is configured yet.

bookmark_borderSunsetting the Maintaina Horde Fork

A few years back I started a downstream fork of Horde to develop features I needed for foss and customer deployments without upstream dependencies. It went successful, was a great learning opportunity and a good exercise in critiquing our old tool chain and approaches. We had some well-known downstream users and contributors but I’d say it has run its course. It’s time to sunset Maintaina in a controlled way that’s fair towards our user base. As we are nearing a beta and prod release of horde 6 proper mostly built from Maintaina, we want to provide a smooth transition.

Horde 6 (upstream) is focusing on supporting PHP 8.4 without spamming warning&notices while Maintaina was originally targeted at PHP 7.4 through 8.1 – Still supporting anything before 8.2 is not a priority with upstream anymore. I will have to discuss with other maintainers of the fork.

Problems to solve:

  • Archive libraries which haven’t been touched for long
  • Coordinate upstreaming libraries with recent changes and archive them
  • Provide a feasible approach to consume only select maintaina packages and mostly upstream packagist
  • Clarify the future of changes downstream users want to keep but which compete with Horde upstream solutions
  • Invite maintainers of downstream code to maintain some upstream libraries to prevent stalling their own needs

I’ll keep you posted.

bookmark_borderPHP: The case for standalone null parameters

PHP 8.0 introduced null and false as members of union types but disallowed them as standalone parameter types. PHP 8.2 changed that and allowed null as standalone parameter types. What is this good for? Should they extend this to “never” one day? Why do I call standalone null parameters poor man’s generics?

What’s a null parameter? What’s a nullable parameter?

A null parameter is a parameter of type null which can only ever have one value null. Its core meaning is “not a value” as opposed to “empty string” or “false” or “zero”.

A union type which has other values but can also contain null is called nullable. For example, boolean is not a nullable type. It has the possible values true and false. If we want to allow a third state, we can create a new nullable type bool|null which has the possible values true, false and null.
In modern php, bool is a union type of true, which can only have the value true, and false, which can only have the value false. So bool|null is equivalent to true|false|null. Union types including null can also be written with a preceding question mark: bool|null is equivalent to ?bool

Isn’t this a bit pointless?

A null parameter by itself is not very interesting. After all, we know its only possible value. It is valuable as a type which can be extended. According to Liskov substitution principle parameters of subtypes should be contravariant to parent types. If the parent type accepts null as a parameter, the child type must accept null as a parameter but may accept anything else. The opposite is true for return types. The child class may have a more specific return type than the parent class but must not return anything the parent would not allow. This is called covariance. In PHP, the top type is called mixed and allows basically everything, even null values. The null type is at the other end of the scale. If the parent returns null, the child must not return anything else. There is one more restricted return type, never. A function of type never must not return at all. It is either an infinite loop or may only exit the whole program. But never is not an allowed parameter type. There is also a return type void which is in between the two. Void may return from functions, but it returns semantically nothing. Not even null.

What is it good for?

Defining an interface parameter as null is allows to define an almost generic interface which might be substantiated in derived classes. Let’s look at an example.

<?php

interface A {

        public function get(null $value): mixed;
}

class B implements A
{
        public function get(null $value): ?object;
        {
                return $value
        }
}

class C extends B
{
        public function get(A|null $value): XmlElement;
        {
            if (is_null($value)
            {
                $value = new SimpleXmlElement("Not Null");
            }

                return $value;
        }
}

class D implements A
{
    public function get(B $value)
    {

    }
}

If you don’t see the point, let me explain. interface A defines that any implementing class must have a method get(null $value) which has only one mandatory parameter. This parameter must accept null as a value. Any additional parameters must be optional. Any derived class may make the first parameter accept more types and even make it optional. The only drawback: Class D cannot be implemented because function get does not accept null as its first parameter $value.

Generics: I wish I had a little more nothing

This is as close to actual generics as one gets with PHP. Generics are code templates which do not have specific parameter and return types until an actual class is created from them. Some other languages do have them but PHP doesn’t. Larry Garfield and others have made the case for them over and over again.

There are some challenges in the engine which make them hard to implement. It would matter less if we had some tbd or changeme type which can only exist in interfaces and can be overridden by any other type. But we don’t. At least we have standalone null.

bookmark_borderStolperfrei: Wir können noch so viel lernen

Ria Weyprecht befasst sich seit über zwei Jahrzehnten mit Web-Gestaltung und Technik – ob nun mit WordPress, anderen Plattformen, Inhouse-Frameworks oder ganz frei. Mindestens seit der Halbzeit spielt auch Barrierefreiheit zunehmend eine Rolle. Mit großem Interesse lese ich seit einiger Zeit auch ihren deutschsprachigen Blog “stolperfrei.digital”. Dort stellt sie immer wieder Techniken vor, mit denen man die Barrierefreiheit von Webseiten verbessern und unnötige Schwierigkeiten vermeiden kann. Ob Zugänglichkeit für Sehbehinderte und Benutzer von Screen Readern, ob Leichte Sprache oder die Vermeidung von Reizüberflutung, immer nah am Stand der aktuellen Forschung und mit Blick auf die Praxis.

Mein beruflicher Schwerpunkt hat sich von Frontend-Belangen immer weiter weg entwickelt. Arbeite ich dann in der Freizeit an Projekten wie Horde Groupware oder JMRI, dann bekommen Profis und Betroffene wahrscheinlich das Grauen. Die technische Basis ist trotz vieler Neuerungen nicht ganz taufrisch und auch das Wissen um den richtigen Einsatz von Gestaltungsmitteln braucht immer mal wieder eine kleine Auffrischung. Es fehlt mir im Frontend auch die handwerkliche Routine und Praxis, die ich tiefer in der Applikation mühelos vorweisen kann. Wie gut, dass im Stolperfrei-Blog immer wieder kleine und große Themen aufgerissen werden. Ich kann direkt überprüfen: Gibt es hier für mich etwas zu tun? Kann ich das Gezeigte anwenden? Oft finde ich auch Hinweise auf weiterführende Themen.

Ich kann nur empfehlen, auch gleich den Newsletter zu abonnieren.

Dies ist keine bezahlte Werbung. Ich bin einfach begeistert.