Commit 216f44d1 authored by David Seaward's avatar David Seaward

On registration, create WooCommerce account

* When user account is created, create a WooCommerce account
* FIXME: Additionally set the WooCommerce password, since the WooCommerce LDAP module is not functionining correctly
* Also, replace "Username" with "$SITE address" in field titles
Signed-off-by: David Seaward's avatarDavid Seaward <david.seaward@puri.sm>
parent 9b55e626
Pipeline #4904 passed with stage
in 38 seconds
from django.conf import settings
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.auth.forms import AuthenticationForm as BaseAuthenticationForm from django.contrib.auth.forms import AuthenticationForm as BaseAuthenticationForm
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
...@@ -5,6 +6,7 @@ from registration.forms import RegistrationForm as BaseRegistrationForm ...@@ -5,6 +6,7 @@ from registration.forms import RegistrationForm as BaseRegistrationForm
from captcha.fields import CaptchaField from captcha.fields import CaptchaField
User = get_user_model() User = get_user_model()
username_title = _(settings.SITE_TITLE + " address")
class AuthenticationForm(BaseAuthenticationForm): class AuthenticationForm(BaseAuthenticationForm):
...@@ -12,6 +14,7 @@ class AuthenticationForm(BaseAuthenticationForm): ...@@ -12,6 +14,7 @@ class AuthenticationForm(BaseAuthenticationForm):
def __init__(self, request=None, *args, **kwargs): def __init__(self, request=None, *args, **kwargs):
super(AuthenticationForm, self).__init__(request, *args, **kwargs) super(AuthenticationForm, self).__init__(request, *args, **kwargs)
self.fields[User.USERNAME_FIELD].label = username_title
self.fields["password"].label = _("Passphrase") self.fields["password"].label = _("Passphrase")
...@@ -21,7 +24,7 @@ class RegistrationForm(BaseRegistrationForm): ...@@ -21,7 +24,7 @@ class RegistrationForm(BaseRegistrationForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(RegistrationForm, self).__init__(*args, **kwargs) super(RegistrationForm, self).__init__(*args, **kwargs)
self.fields[User.USERNAME_FIELD].label = _("Username") self.fields[User.USERNAME_FIELD].label = username_title
self.fields["password1"].label = _("Passphrase") self.fields["password1"].label = _("Passphrase")
self.fields["password2"].label = _("Passphrase confirmation") self.fields["password2"].label = _("Passphrase confirmation")
self.fields["password2"].help_text = _("Enter the same passphrase as before, for verification.") self.fields["password2"].help_text = _("Enter the same passphrase as before, for verification.")
......
...@@ -3,27 +3,39 @@ import logging ...@@ -3,27 +3,39 @@ import logging
from django.conf import settings from django.conf import settings
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
from django.contrib.auth.models import UserManager as BaseUserManager from django.contrib.auth.models import UserManager as BaseUserManager
from django.contrib.auth.hashers import make_password
from django.core import validators from django.core import validators
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
from django.utils.crypto import salted_hmac from django.utils.crypto import salted_hmac
from django.utils.deconstruct import deconstructible from django.utils.deconstruct import deconstructible
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from ldapregister.models import LdapPerson from ldapregister.models import LdapPerson
from limitmonitor import models as limitmonitor_models from limitmonitor import models as limitmonitor_models
from limitmonitor.task_resources import common as limitmonitor_common from limitmonitor.task_resources import common as limitmonitor_common
from limitmonitor.tunnel import TunnelManager from limitmonitor.tunnel import TunnelManager
from cryptography.fernet import Fernet from cryptography.fernet import Fernet
from woocommerce import API as WOO_API
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
def get_woo_connection():
return WOO_API(
url=settings.WOO_URL,
consumer_key=settings.WOO_CONSUMER_KEY,
consumer_secret=settings.WOO_CONSUMER_SECRET,
wp_api=settings.WOO_WP_API,
version=settings.WOO_VERSION,
query_string_auth=settings.WOO_QUERY_STRING_AUTH,
)
@deconstructible @deconstructible
class UsernameValidator(validators.RegexValidator): class UsernameValidator(validators.RegexValidator):
regex = r'^[A-Za-z][A-Za-z0-9]*$' regex = r'^[A-Za-z][A-Za-z0-9]*$'
message = _( message = _(
'Enter a valid username. Must start with a letter, followed by letters and numbers.' 'Enter a valid address prefix. Must start with a letter, followed by letters or numbers.'
' No punctuation or special characters.' ' No punctuation or special characters.'
) )
...@@ -45,15 +57,16 @@ class User(AbstractUser): ...@@ -45,15 +57,16 @@ class User(AbstractUser):
objects = UserManager() objects = UserManager()
REQUIRED_FIELDS = [] REQUIRED_FIELDS = []
username_validator = UsernameValidator() username_validator = UsernameValidator()
woo_connection = None
username = models.CharField( username = models.CharField(
_('username'), _('username'),
max_length=150, max_length=150,
unique=True, unique=True,
help_text=_('Required. Start with a letter, followed by letters and numbers.'), help_text=_('Required. Start with a letter, followed by letters or numbers.'),
validators=[username_validator], validators=[username_validator],
error_messages={ error_messages={
'unique': _("A user with that username already exists."), 'unique': _("An account with that address already exists."),
}, },
) )
...@@ -89,6 +102,79 @@ class User(AbstractUser): ...@@ -89,6 +102,79 @@ class User(AbstractUser):
ldap_person = self.get_ldap() ldap_person = self.get_ldap()
ldap_person.change_password(raw_password) ldap_person.change_password(raw_password)
def woo_get_json(self, query):
try:
if self.woo_connection is None:
woo = get_woo_connection()
result = woo.get(query).json()
except Exception as e:
logging.exception("Could not retrieve WooCommerce ID with query " + query)
result = None
return result
def woo_post_json(self, query, data):
try:
if self.woo_connection is None:
woo = get_woo_connection()
result = woo.post(query, data).json()
except Exception as e:
logging.exception("Could not post " + query + " with data " + str(data))
result = None
return result
def woo_put_json(self, query, data):
try:
if self.woo_connection is None:
woo = get_woo_connection()
result = woo.put(query, data).json()
except Exception as e:
logging.exception("Could not put " + query + " with data " + str(data))
result = None
return result
def get_woocommerce_id(self):
query = "customers?email=" + self.get_identity()
json = self.woo_get_json(query)
if len(json) == 1:
return json[0]["id"]
return None
def create_woocommerce_account(self):
query = "customers"
data = {
"email": self.get_identity(),
"first_name": self.username,
"last_name": settings.SITE_TITLE,
"username": self.get_identity(),
"password": make_password(None), # unusable password
}
return self.woo_post_json(query, data)
def set_woocommerce_password(self, raw_password, woocommerce_id=None):
if woocommerce_id is None:
woocommerce_id = self.get_woocommerce_id()
query = "customers/" + str(woocommerce_id)
data = {
"password": raw_password,
}
return self.woo_put_json(query, data)
def get_identity(self): def get_identity(self):
return self.get_username() + "@" + settings.SITE_DOMAIN.lower() return self.get_username() + "@" + settings.SITE_DOMAIN.lower()
...@@ -104,6 +190,10 @@ class User(AbstractUser): ...@@ -104,6 +190,10 @@ class User(AbstractUser):
# force null Django password (will use LDAP password instead) # force null Django password (will use LDAP password instead)
self.set_unusable_password() self.set_unusable_password()
# create WooCommerce account (if required)
if self.get_woocommerce_id() is None:
self.create_woocommerce_account()
# create any missing limits # create any missing limits
limitmonitor_models.create_missing_user_limits(self) limitmonitor_models.create_missing_user_limits(self)
...@@ -134,6 +224,12 @@ class User(AbstractUser): ...@@ -134,6 +224,12 @@ class User(AbstractUser):
# set LDAP password # set LDAP password
self.set_ldap_password(raw_password) self.set_ldap_password(raw_password)
# FIXME: we actually need to update WooCommerce LDAP authentication
if self.get_woocommerce_id() is None:
self.create_woocommerce_account()
self.set_woocommerce_password(raw_password)
def get_session_auth_hash(self): def get_session_auth_hash(self):
""" """
Return an HMAC of the password field. Return an HMAC of the password field.
......
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