Commit 764cc8a3 authored by David Seaward's avatar David Seaward

* always use query_string_auth flag for woocommerce connections

* define get_username_from_woo_customer_id
* FIXME: hardcode ID for subscription parser
* filter for known product IDs
* fix parser name in display
* update config to match new requirements
* tweak setup instructions to match updates
parent c88d45cc
......@@ -25,7 +25,6 @@ Prerequisites
* [REST API enabled](https://docs.woocommerce.com/document/woocommerce-rest-api/)
* [WooCommerce Subscriptions](https://woocommerce.com/products/woocommerce-subscriptions/)
* [JWT Authentication for WP REST API](https://wordpress.org/plugins/jwt-authentication-for-wp-rest-api/)
(pending)
* OpenVPN instance (SSH access)
* Including [openvpn-confgen](https://plan.puri.st/module/openvpn_confgen)
* Typically, the Nginx user (`www-data`) will need SSH access
......@@ -88,16 +87,23 @@ Setup
* `sudo service nginx restart`
* `sudo service supervisor restart`
* Check logs:
* `/var/log/uwsgi/emperor.log`
* `/var/log/uwsgi/app/purist_middleware.log`
* `/var/log/nginx/error.log`
* `/var/log/nginx/access.log`
* `/var/log/supervisor/supervisord.log`
* `/var/log/nginx/error.log`
* `/var/log/purist/middleware/beat.log`
* `/var/log/supervisor/supervisord.log`
* `/var/log/uwsgi/emperor.log`
* `/var/log/uwsgi/app/purist_middleware.log`
For more options and details see
<https://docs.djangoproject.com/en/1.11/#the-development-process>
Configure
---------
* Log in as admin
* Define an interval in Django_Celery_Beat > Intervals
* Define a periodic task(s) in Django_Celery_Beat > Periodic tasks
Update
------
......
......@@ -11,6 +11,7 @@ DEBUG=True
DEBUG_ALL_ACCESS=True
DEBUG_CHANGE_PASSWORD=False
DEBUG_SKIP_ACTIVATION_COMMAND=True
DEBUG_SKIP_VALIDATE_ON_AUTHENTICATION = False
# change to false after initial setup
ALLOWED_HOSTS=localhost
STATIC_ROOT=/var/opt/purist/middleware/static
......@@ -28,11 +29,10 @@ STATICFILES_DIRS=/var/opt/purist/brand,/var/opt/purist/downloads
WOO_URL=https://example.com
WOO_WP_API=True
WOO_VERSION=wc/v1
WOO_PRODUCT_LIST=123,124
WOO1_FIELD_LIST=Existing username,Username
WOO_QUERY_STRING_AUTH = True
WOOSUB1_PRODUCT_LIST = 123,124
OVPN_HOSTNAME=ssh.example.com
OVPN_PORT=22
OVPN_USERNAME=username
OVPN_FILEPATH="/path/to/{IDENTITY}/{IDENTITY}.ovpn"
SUBSCRIPTION_LINK=https://www.example.com
......@@ -133,7 +133,7 @@ class ExternalCredit(models.Model):
@property
def parser_name(self):
settings.LM_PARSERS.get_name_by_code(self.parser)
return settings.LM_PARSERS.get_name_by_code(self.parser)
@property
def external_code(self):
......
......@@ -20,9 +20,25 @@ def get_woo_connection():
consumer_secret=settings.WOO_CONSUMER_SECRET,
wp_api=settings.WOO_WP_API,
version=settings.WOO_VERSION,
query_string_auth=settings.WOO_QUERY_STRING_AUTH,
)
def get_username_from_woo_customer_id(customer_id, woo=None):
if woo is None:
woo = get_woo_connection()
try:
query = "customers/" + str(customer_id)
result = woo.get(query).json()
return result["username"] + "@" + settings.SITE_DOMAIN
except Exception as e:
logger.exception("Could not retrieve username for customer_id " + str(customer_id))
return "invalid"
return account
def get_openvpn_ssh_connection():
# make ssh connection to OpenVPN server
# (uses system host keys, warns if host is not recognised)
......@@ -124,24 +140,6 @@ def deactivate(ssh, limit):
limit.save()
def get_account_from_woo_meta(meta_list):
account = "invalid"
for meta_item in meta_list:
if meta_item["key"] in settings.WOO1_FIELD_LIST: # for example, "Existing username,"
account = meta_item["value"]
at_count = account.count("@")
if at_count == 0: # nodomain
account += "@" + settings.SITE_DOMAIN # corrected to nodomain@example.com
elif at_count == 1:
pass # valid account format
else: # at_count > 1, for example bad@user@example.com
account = account.replace("@", ".AT.") # force invalid name bad.AT.user.AT.example.com
return account
def get_limit_objects(credit):
# get and validate local username
......@@ -174,22 +172,22 @@ def store_credit_and_update_limit(ssh, credit, next_renewal=None):
if credit.parser == "WOO1":
from .tunnel_credit import update_limit_woo1
update_limit_woo1(ssh, credit)
elif credit.parser == "WOOSUB1":
elif credit.parser == 2: # FIXME: this is WOO_SUBSCRIPTION_V1 from purist.limitmonitor
from .tunnel_subscription import update_limit_woosub1
update_limit_woosub1(ssh, credit, next_renewal)
else:
raise Exception("Unrecognised parser " + credit.parser)
raise Exception("Unrecognised Parser " + str(credit.parser))
credit.is_converted = True
credit.error_message = ""
except Exception as e:
message = "Skipped adding credit " + credit.parser + ":" + credit.external_key + ". "
message = "Skipped adding credit Parser " + str(credit.parser) + ": " + credit.external_key + ". "
logger.exception(message)
credit.error_message = message + repr(e)
finally:
credit.save()
state = "converted" if credit.is_converted else "skipped"
logger.info("Stored " + state + " credit " + credit.parser + ":" + credit.external_key)
logger.info("Stored " + state + " credit Parser " + str(credit.parser) + ": " + credit.external_key)
def deactivate_all_expired_limits():
......
......@@ -17,7 +17,7 @@ def parse_woo1(json_entry, product_id):
product_id = line_item["product_id"]
product_label = line_item["name"]
quantity = line_item["quantity"]
account = get_account_from_woo_meta(line_item["meta"])
account = None # FIXME: need to get the account
external_key = str(order_id) + ":" + str(item_id)
external_label = str(order_name)
......
......@@ -23,16 +23,19 @@ def parse_woosub1(json_entry):
next_renewal_naive = datetime.datetime.strptime(json_entry["next_payment_date"], "%Y-%m-%dT%H:%M:%S")
next_renewal = timezone.make_aware(next_renewal_naive)
# get account name
username = get_username_from_woo_customer_id(json_entry["customer_id"])
# create result
result = {
"parser": "WOOSUB1",
"parser": 2, # FIXME: this is WOO_SUBSCRIPTION_V1 from purist.limitmonitor
"external_key": subscription_id,
"label": json_entry["number"],
"bundle_key": str(line_item["product_id"]),
"bundle_label": str(line_item["name"]),
"quantity": 1,
"account": get_account_from_woo_meta(line_item["meta"]),
"account": username,
"next_renewal": next_renewal,
}
......@@ -52,7 +55,9 @@ def monitor_woosub1_new_subscriptions():
# parse recent subscriptions and store results
for json_entry in latest_subscription_json:
try:
result_list.extend(parse_woosub1(json_entry))
product_id = int(json_entry["line_items"][0]["product_id"])
if product_id in settings.WOOSUB1_PRODUCT_LIST:
result_list.extend(parse_woosub1(json_entry))
except Exception as e:
logger.exception("Skipping JSON entry " + str(json_entry))
......
......@@ -144,17 +144,16 @@ SITE_PROVIDER_LINK = config("SITE_PROVIDER_LINK")
WOO_URL = config("WOO_URL")
WOO_WP_API = config("WOO_WP_API", cast=bool)
WOO_VERSION = config("WOO_VERSION")
WOO_QUERY_STRING_AUTH = config("WOO_QUERY_STRING_AUTH", cast=bool) # required for OAuth over HTTPS
WOO_CONSUMER_KEY = secret_config("WOO_CONSUMER_KEY")
WOO_CONSUMER_SECRET = secret_config("WOO_CONSUMER_SECRET")
WOO_PRODUCT_LIST = config("WOO_PRODUCT_LIST", cast=Csv(int))
#
# WOO1 PARSER
# WOOSUB1 PARSER
#
WOO1_FIELD_LIST = config("WOO1_FIELD_LIST", cast=Csv())
WOOSUB1_PRODUCT_LIST = config("WOOSUB1_PRODUCT_LIST", cast=Csv(int))
#
# SSH CONNECTION TO OPENVPN SERVER
......
......@@ -28,7 +28,7 @@ class AuthenticationBackend(BaseBackend):
consumer_secret=settings.WOO_CONSUMER_SECRET,
wp_api=True,
version="jwt-auth/v1", # required for JWT Authentication
query_string_auth=True, # required for OAuth over HTTPS
query_string_auth=settings.WOO_QUERY_STRING_AUTH,
)
jwt_response = jwt_wcapi.post("token", {"username": username, "password": password})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment