126 lines
4 KiB
Python
126 lines
4 KiB
Python
import json
|
|
import logging
|
|
|
|
import requests
|
|
from django.conf import settings
|
|
from django.core.cache import cache
|
|
from license_info.exeptions import LicenseException
|
|
|
|
LICENSE_CLIENT_URL = getattr(settings, 'LICENSE_CLIENT_URL', '')
|
|
LICENSE_CACHE_TIMEOUT = getattr(settings, 'LICENSE_CACHE_TIMEOUT', 60 * 60)
|
|
|
|
LICENSE_KEY = "license_key"
|
|
LICENSE_INFO_URL = f"{LICENSE_CLIENT_URL}/license/"
|
|
LICENSE_TOKEN_URL = f"{LICENSE_CLIENT_URL}/token/"
|
|
LICENSE_ACTIVATE_URL = f"{LICENSE_CLIENT_URL}/activate/"
|
|
LICENSE_AUTO_ACTIVATE_URL = f"{LICENSE_CLIENT_URL}/auto/"
|
|
|
|
_log = logging.getLogger()
|
|
|
|
|
|
def check_response(response):
|
|
"""Check that license client's response has no error
|
|
@param response: is a requests.response object
|
|
@raise RuntimeError if response isn't good
|
|
@return parsed response"""
|
|
if response.status_code != 200:
|
|
_log.error(f"Can't get license info {response}")
|
|
raise LicenseException("Bad license client response code")
|
|
|
|
try:
|
|
data = response.json()
|
|
except json.JSONDecodeError:
|
|
_log.error(f"Can't parse json response: {response.content}")
|
|
raise LicenseException("Can't parse client's json")
|
|
|
|
# Need to check for error
|
|
if data["status"] != "ok":
|
|
_log.error(f"Got error from client: {data['reason']}")
|
|
raise LicenseException("Bad client response")
|
|
|
|
return data["response"]
|
|
|
|
|
|
def get_license_info():
|
|
"""Get current license info
|
|
This function will use cached value most of the time
|
|
@raise RuntimeError if something go wrong
|
|
@return license info"""
|
|
license_data = cache.get(LICENSE_KEY)
|
|
if isinstance(license_data, dict):
|
|
return license_data
|
|
|
|
# Need to query for license info from client
|
|
response = requests.get(LICENSE_INFO_URL)
|
|
license_data = check_response(response)
|
|
|
|
try:
|
|
license_data['options']['event_sources'] = int(license_data['options']['event_sources'])
|
|
except KeyError:
|
|
if 'options' not in license_data:
|
|
license_data['options'] = {}
|
|
if 'event_sources' not in license_data['options']:
|
|
license_data['options']['event_sources'] = 0
|
|
except ValueError:
|
|
license_data['options']['event_sources'] = 0
|
|
|
|
# Save license to cache
|
|
cache.set(LICENSE_KEY, license_data, LICENSE_CACHE_TIMEOUT)
|
|
_log.debug("License information updated")
|
|
return license_data
|
|
|
|
|
|
def get_activation_token(serial):
|
|
"""Get activation token
|
|
@param serial: application serial number
|
|
@raise RuntimeError if something goes wrong
|
|
@return activation token as string"""
|
|
|
|
response = requests.get(LICENSE_TOKEN_URL, params={"serial": serial})
|
|
return check_response(response)
|
|
|
|
|
|
def activate_license(license_json):
|
|
"""Activate license from license server
|
|
@param license_json: License that we got from license server
|
|
@raise RuntimeError if something goes wrong"""
|
|
|
|
response = requests.post(LICENSE_ACTIVATE_URL, json=license_json)
|
|
data = check_response(response)
|
|
cache.set(LICENSE_KEY, data, LICENSE_CACHE_TIMEOUT)
|
|
|
|
_log.info("License activated")
|
|
|
|
|
|
def activate_license_auto(serial):
|
|
"""Activate license via activations server
|
|
@param serial: application serial number
|
|
@raise RuntimeError if something goes wrong"""
|
|
|
|
response = requests.get(LICENSE_AUTO_ACTIVATE_URL, params={"serial": serial})
|
|
data = check_response(response)
|
|
|
|
# Save license to cache
|
|
cache.set(LICENSE_KEY, data, LICENSE_CACHE_TIMEOUT)
|
|
_log.info("License activated via license server")
|
|
|
|
|
|
def check_features(features):
|
|
"""
|
|
Check if license has requested features
|
|
@param features: List of strings with features names
|
|
@return: True if license has ALL features and False if not
|
|
"""
|
|
try:
|
|
info = get_license_info()
|
|
if isinstance(features, (list, tuple)):
|
|
for cur in features:
|
|
if cur not in info["features"]:
|
|
return False
|
|
return True
|
|
elif isinstance(features, str):
|
|
return features in info["features"]
|
|
else:
|
|
return False
|
|
except:
|
|
return False
|