Repository: privacyidea/privacyidea

Issue:
enhance subscription definitions
We should add

* [x] "privacyidea-adfs"
* [x] "privacyidea-keycloak"
* [x] "simplesamlphp"
* [x] "privacyidea-simplesamlphp"

into subscription.py.

We can also enhance the subscription e.g. for push-tokens or the privacyIDEA authenticator app, which can be checked, when we provide additional enterprise features for the authenticator app.

There are two different types of subscriptions, the client-subscriptions (privacyidea-adfs, privacyidea-cp...) which are checked during authentication. And the kind of server or token subscriptions (privacyidea, privacyidea-app...) which are checked during login at the webui.
We could also rework the subscription definition in this way, that we also add the information, which "type" the subscription is.

In `lib/subscription.py:subscription_status()` we could return a list of tuples like:

    [ ("privacyidea": 3), ("privacyidea-app": 1) ]

indicating that the server subscription is fine, but the app subscription is exceeded.

# Note

"privacyIDEA-App" is the UserAgent that is used when the App communicates to the privacyIDEA server.
Currently we are issuing "privacyIDEA Authenticator".

The question is: *What do we want to do, when the  subscription for the App is exceeded?*

1. ~~Fail on Push authentication like with CP or~~
2.  Simply notify in the WebUI like with the privacyIDEA server subscription.


Discussion:

Resolving patch:
diff --git a/privacyidea/api/lib/postpolicy.py b/privacyidea/api/lib/postpolicy.py
--- a/privacyidea/api/lib/postpolicy.py
+++ b/privacyidea/api/lib/postpolicy.py
@@ -594,6 +594,8 @@ def get_webui_settings(request, response):
         content["result"]["value"]["show_seed"] = show_seed
         content["result"]["value"]["show_node"] = get_privacyidea_node() if show_node else ""
         content["result"]["value"]["subscription_status"] = subscription_status()
+        content["result"]["value"]["subscription_status_push"] = subscription_status("privacyidea authenticator",
+                                                                                     tokentype="push")
         content["result"]["value"]["qr_image_android"] = qr_image_android
         content["result"]["value"]["qr_image_ios"] = qr_image_ios
         content["result"]["value"]["qr_image_custom"] = qr_image_custom
diff --git a/privacyidea/lib/subscriptions.py b/privacyidea/lib/subscriptions.py
--- a/privacyidea/lib/subscriptions.py
+++ b/privacyidea/lib/subscriptions.py
@@ -71,6 +71,10 @@
                 "privacyidea-ldap-proxy": 50,
                 "privacyidea-cp": 50,
                 "privacyidea-adfs": 50,
+                "privacyidea-keycloak": 10000,
+                "simplesamlphp": 10000,
+                "privacyidea-simplesamlphp": 10000,
+                "privacyidea authenticator": 10,
                 "privacyidea": 50}
 
 log = logging.getLogger(__name__)
@@ -89,7 +93,7 @@ def get_users_with_active_tokens():
     return sql_query.count()
 
 
-def subscription_status():
+def subscription_status(component="privacyidea", tokentype=None):
     """
     Return the status of the subscription
 
@@ -100,16 +104,16 @@ def subscription_status():
 
     :return: subscription state
     """
-    token_count = get_tokens(assigned=True, active=True, count=True)
-    if token_count <= APPLICATIONS.get("privacyidea", 50):
+    token_count = get_tokens(assigned=True, active=True, count=True, tokentype=tokentype)
+    if token_count <= APPLICATIONS.get(component, 50):
         return 0
 
-    subscriptions = get_subscription("privacyidea")
+    subscriptions = get_subscription(component)
     if len(subscriptions) == 0:
         return 1
 
     try:
-        check_subscription("privacyidea")
+        check_subscription(component)
     except SubscriptionError as exx:
         log.warning(u"{0}".format(exx))
         return 2
@@ -262,7 +266,7 @@ def check_subscription(application, max_free_subscriptions=None):
                     raise SubscriptionError(description="Too many users "
                                                         "with assigned tokens. "
                                                         "Subscription exceeded.",
-                                            application="privacyIDEA")
+                                            application=application)
 
     return True
 


Test patch: