mirror of https://github.com/zulip/zulip.git
api: Add a monotonic integer "feature level" for non-webapp clients.
The purpose is to provide a way for (non-webapp) clients, like the mobile and terminal apps, to tell whether the server it's talking to is new enough to support a given API feature -- in particular a way that * is finer-grained than release numbers, so that for features developed after e.g. 2.1.0 we can use them immediately on servers deployed from master (like chat.zulip.org and zulipchat.com) without waiting the months until a 2.2 release; * is reliable, unlike e.g. looking at the number of commits since a release; * doesn't lead to a growing bag of named feature flags which the server has to go on sending forever. Tweaked by tabbott to extend the documentation. Closes #14618.
This commit is contained in:
parent
0de77cabb0
commit
e3b90a5ec8
|
@ -36,6 +36,16 @@ Fetch global settings for a Zulip server.
|
||||||
* `authentication_methods`: object in which each key-value pair in the object
|
* `authentication_methods`: object in which each key-value pair in the object
|
||||||
indicates whether the authentication method is enabled on this server.
|
indicates whether the authentication method is enabled on this server.
|
||||||
* `zulip_version`: the version of Zulip running in the server.
|
* `zulip_version`: the version of Zulip running in the server.
|
||||||
|
* `zulip_feature_level`: an integer indicatating what features are
|
||||||
|
available on the server. The feature level increases monotonically;
|
||||||
|
a value of N means the server supports all API features introduced
|
||||||
|
before feature level N. This is designed to provide a simple way
|
||||||
|
for mobile apps to decide whether the server supports a given
|
||||||
|
feature or API change.
|
||||||
|
|
||||||
|
**Changes**. New in Zulip 2.2. We recommend using an implied value
|
||||||
|
of 0 for Zulip servers that do not send this field.
|
||||||
|
|
||||||
* `push_notifications_enabled`: whether mobile/push notifications are enabled.
|
* `push_notifications_enabled`: whether mobile/push notifications are enabled.
|
||||||
* `is_incompatible`: whether the Zulip client that has sent a request to
|
* `is_incompatible`: whether the Zulip client that has sent a request to
|
||||||
this endpoint is deemed incompatible with the server.
|
this endpoint is deemed incompatible with the server.
|
||||||
|
|
10
version.py
10
version.py
|
@ -21,6 +21,16 @@ LATEST_DESKTOP_VERSION = "5.0.0"
|
||||||
DESKTOP_MINIMUM_VERSION = "5.0.0"
|
DESKTOP_MINIMUM_VERSION = "5.0.0"
|
||||||
DESKTOP_WARNING_VERSION = "5.0.0"
|
DESKTOP_WARNING_VERSION = "5.0.0"
|
||||||
|
|
||||||
|
# Bump the API_FEATURE_LEVEL whenever an API change is made
|
||||||
|
# that clients might want to condition on. If we forget at
|
||||||
|
# the time we make the change, then bump it later as soon
|
||||||
|
# as we notice; clients using API_FEATURE_LEVEL will just not
|
||||||
|
# use the new feature/API until the bump.
|
||||||
|
#
|
||||||
|
# Changes should be accompanied by documentation explaining what the new
|
||||||
|
# level means in templates/zerver/api/server-settings.md.
|
||||||
|
API_FEATURE_LEVEL = 1
|
||||||
|
|
||||||
# Bump the minor PROVISION_VERSION to indicate that folks should provision
|
# Bump the minor PROVISION_VERSION to indicate that folks should provision
|
||||||
# only when going from an old version of the code to a newer version. Bump
|
# only when going from an old version of the code to a newer version. Bump
|
||||||
# the major version to indicate that folks should provision in both
|
# the major version to indicate that folks should provision in both
|
||||||
|
|
|
@ -59,7 +59,7 @@ from zerver.models import (
|
||||||
get_default_stream_groups, CustomProfileField, Stream
|
get_default_stream_groups, CustomProfileField, Stream
|
||||||
)
|
)
|
||||||
from zproject.backends import email_auth_enabled, password_auth_enabled
|
from zproject.backends import email_auth_enabled, password_auth_enabled
|
||||||
from version import ZULIP_VERSION
|
from version import ZULIP_VERSION, API_FEATURE_LEVEL
|
||||||
from zerver.lib.external_accounts import DEFAULT_EXTERNAL_ACCOUNTS
|
from zerver.lib.external_accounts import DEFAULT_EXTERNAL_ACCOUNTS
|
||||||
|
|
||||||
def add_realm_logo_fields(state: Dict[str, Any], realm: Realm) -> None:
|
def add_realm_logo_fields(state: Dict[str, Any], realm: Realm) -> None:
|
||||||
|
@ -312,6 +312,7 @@ def fetch_initial_state_data(user_profile: UserProfile,
|
||||||
|
|
||||||
if want('zulip_version'):
|
if want('zulip_version'):
|
||||||
state['zulip_version'] = ZULIP_VERSION
|
state['zulip_version'] = ZULIP_VERSION
|
||||||
|
state['zulip_feature_level'] = API_FEATURE_LEVEL
|
||||||
|
|
||||||
return state
|
return state
|
||||||
|
|
||||||
|
|
|
@ -2450,6 +2450,15 @@ paths:
|
||||||
type: string
|
type: string
|
||||||
description: |
|
description: |
|
||||||
The version of Zulip running in the server.
|
The version of Zulip running in the server.
|
||||||
|
zulip_feature_level:
|
||||||
|
type: integer
|
||||||
|
description: |
|
||||||
|
An integer to indicate the features added to the server.
|
||||||
|
The feature level increases monotonically; a value of N
|
||||||
|
means the server supports all API features introduced
|
||||||
|
before feature level N. This provides fine-grained
|
||||||
|
distinctions among development versions in between major
|
||||||
|
releases.
|
||||||
push_notifications_enabled:
|
push_notifications_enabled:
|
||||||
type: boolean
|
type: boolean
|
||||||
description: |
|
description: |
|
||||||
|
|
|
@ -38,7 +38,7 @@ from zerver.lib.email_validation import get_realm_email_validator, \
|
||||||
from zerver.lib.exceptions import RateLimited
|
from zerver.lib.exceptions import RateLimited
|
||||||
from zerver.lib.mobile_auth_otp import otp_decrypt_api_key
|
from zerver.lib.mobile_auth_otp import otp_decrypt_api_key
|
||||||
from zerver.lib.validator import validate_login_email, \
|
from zerver.lib.validator import validate_login_email, \
|
||||||
check_bool, check_dict_only, check_list, check_string, Validator
|
check_bool, check_dict_only, check_list, check_string, check_int, Validator
|
||||||
from zerver.lib.rate_limiter import add_ratelimit_rule, remove_ratelimit_rule
|
from zerver.lib.rate_limiter import add_ratelimit_rule, remove_ratelimit_rule
|
||||||
from zerver.lib.request import JsonableError
|
from zerver.lib.request import JsonableError
|
||||||
from zerver.lib.storage import static_path
|
from zerver.lib.storage import static_path
|
||||||
|
@ -2552,6 +2552,7 @@ class FetchAuthBackends(ZulipTestCase):
|
||||||
('require_email_format_usernames', check_bool),
|
('require_email_format_usernames', check_bool),
|
||||||
('realm_uri', check_string),
|
('realm_uri', check_string),
|
||||||
('zulip_version', check_string),
|
('zulip_version', check_string),
|
||||||
|
('zulip_feature_level', check_int),
|
||||||
('push_notifications_enabled', check_bool),
|
('push_notifications_enabled', check_bool),
|
||||||
('msg', check_string),
|
('msg', check_string),
|
||||||
('result', check_string),
|
('result', check_string),
|
||||||
|
|
|
@ -224,6 +224,7 @@ class HomeTest(ZulipTestCase):
|
||||||
"warn_no_email",
|
"warn_no_email",
|
||||||
"webpack_public_path",
|
"webpack_public_path",
|
||||||
"wildcard_mentions_notify",
|
"wildcard_mentions_notify",
|
||||||
|
"zulip_feature_level",
|
||||||
"zulip_version",
|
"zulip_version",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ from zproject.backends import password_auth_enabled, dev_auth_enabled, \
|
||||||
ldap_auth_enabled, ZulipLDAPConfigurationError, ZulipLDAPAuthBackend, \
|
ldap_auth_enabled, ZulipLDAPConfigurationError, ZulipLDAPAuthBackend, \
|
||||||
AUTH_BACKEND_NAME_MAP, auth_enabled_helper, saml_auth_enabled, SAMLAuthBackend, \
|
AUTH_BACKEND_NAME_MAP, auth_enabled_helper, saml_auth_enabled, SAMLAuthBackend, \
|
||||||
redirect_to_config_error, ZulipRemoteUserBackend, validate_otp_params
|
redirect_to_config_error, ZulipRemoteUserBackend, validate_otp_params
|
||||||
from version import ZULIP_VERSION
|
from version import ZULIP_VERSION, API_FEATURE_LEVEL
|
||||||
|
|
||||||
import jwt
|
import jwt
|
||||||
import logging
|
import logging
|
||||||
|
@ -946,6 +946,7 @@ def api_get_server_settings(request: HttpRequest) -> HttpResponse:
|
||||||
result = dict(
|
result = dict(
|
||||||
authentication_methods=get_auth_backends_data(request),
|
authentication_methods=get_auth_backends_data(request),
|
||||||
zulip_version=ZULIP_VERSION,
|
zulip_version=ZULIP_VERSION,
|
||||||
|
zulip_feature_level=API_FEATURE_LEVEL,
|
||||||
push_notifications_enabled=push_notifications_enabled(),
|
push_notifications_enabled=push_notifications_enabled(),
|
||||||
is_incompatible=check_server_incompatibility(request),
|
is_incompatible=check_server_incompatibility(request),
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue