Skip to content
This repository has been archived by the owner on Apr 8, 2024. It is now read-only.

Subscription form #624

Merged
merged 43 commits into from
Sep 13, 2017
Merged

Subscription form #624

merged 43 commits into from
Sep 13, 2017

Conversation

vaninawohlleb
Copy link
Contributor

@vaninawohlleb vaninawohlleb commented Aug 23, 2017

  • create a new create_subscritption handler
  • remove submit-subscription handler?
  • implements more specific error handling
  • removes the check for POSt request (hm maybe we should revert this change actually)

This should be tested along with this PR (https://github.com/LeastAuthority/leastauthority.com-website/pull/56). For testing instructions check the above PR


class CreateSubscription(HandlerBase):
def addHeaders(self, request):
request.setHeader('Access-Control-Allow-Origin', 'http://localhost:5000')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this shouldnt be hardcoded as we will need different domains for different environments. @exarkun what would be your suggestion for most secure way of adding this to the server vars?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this address meant to point at? Is it the main leastauthority website (where the signup form is hosted)? What are the consequences of this header?

As far as getting configuration into the server, that will probably start by adding something to k8s/secrets.{staging,production}.enc.yaml, updating k8s/infrastructure.yaml to extract that new secret item and pass it as an argument to lae_site.main, and then updating lae_site.main to take the new parameter and pass it onwards to the code that needs it (CreateSubscription). Possibly the first part is done already: we already have a domain secret item, we just haven't needed it in lae_site before.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this address is the client lektor site, and the header allows cross origin requests. So it will be different in staging and production environments

Copy link
Contributor

@exarkun exarkun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Various comments about the code inline. Comments about the user-facing experience on the other PR.


class CreateSubscription(HandlerBase):
def addHeaders(self, request):
request.setHeader('Access-Control-Allow-Origin', 'http://localhost:5000')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this address meant to point at? Is it the main leastauthority website (where the signup form is hosted)? What are the consequences of this header?

As far as getting configuration into the server, that will probably start by adding something to k8s/secrets.{staging,production}.enc.yaml, updating k8s/infrastructure.yaml to extract that new secret item and pass it as an argument to lae_site.main, and then updating lae_site.main to take the new parameter and pass it onwards to the code that needs it (CreateSubscription). Possibly the first part is done already: we already have a domain secret item, we just haven't needed it in lae_site before.

)

class CreateSubscription(HandlerBase):
def addHeaders(self, request):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use 4 space indents everywhere. Though Python gives you freedom to choose, 4 space indents is the only correct choice. :)

@@ -195,8 +195,6 @@ def main(reactor, *argv):
d.addCallback(lambda ignored: Deferred())
return d



def site_for_options(reactor, options):
provisioner = get_provisioner(
reactor,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just whitespace changes in this file, I think. Please revert.

@@ -8,8 +8,10 @@
from twisted.python.filepath import FilePath

from lae_site.handlers.web import JinjaHandler
# TODO: Rename all handlers teh same way for consistency
from lae_site.handlers.submit_subscription import SubmitSubscriptionHandler
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import could be removed now. SubmitSubscriptionHandler is no longer used. Perhaps all of submit_subscription.py can be removed, in fact. It looks like everything it was doing is now done in create_subscription.py. There are a couple other areas of code that try to import from submit_subscription - eg lae_site/main.py imports Stripe and Mailer from it but there are copies of those classes defined in create_subscription.py now so those imports could be switched.

The tests for submit_subscription.py can perhaps also be adapted to create_subscription.py. See lae_site/handlers/test/test_submit_subscription.py.

@attr.s
class Stripe(object):
key = attr.ib()
# email = "vtsoneva@gmail.com"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some more dev/debug cruft to remove

@@ -0,0 +1,169 @@
from twisted.web.resource import Resource
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import appears unused.

self.handle_stripe_create_customer_errors(traceback.format_exc(100), e,
details=e.message.encode("utf-8"),
email_subject="Stripe Card error",
notes=note)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I liked the old formatting better. 😁

self.handle_stripe_create_customer_errors(traceback.format_exc(100), e,
details="Something went wrong. Please try again, or contact"+
"support@leastauthority.com.",
email_subject="Stripe unexpected error")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like some changes from master have been lost. There was a recent change to make these email_subject parameters all include the email address the user had entered. Those changes are present in submit_subscription.py but they aren't included here, I guess because you started from the version before they were introduced.

It seems that create_subscription.py and submit_subscription.py are substantially the same. In the future it would be easier (because of better tool support) to just edit in-place. For example, in this case, that would have let git merge the master changes in with yours (or at least show you conflict markers around areas that need your merge attention). This is also an argument in favor of leaving formatting alone (except in extreme circumstances) since formatting changes often result in merge conflicts that have to be resolved (tedious) for no significant benefit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about it a little more, the easiest thing to do at this point might be to read through the git patch log for create_subscription.py and apply the patches (perhaps manually 😢) onto submit_subscription.py. Then git rm create_subscription.pyfrom the branch (and perhapsgit mv submit_subscription.py create_subscription.py`).

Let me know if I can help with any of the git operations.


{% extends '_base.html' %}
{% block content %}

<h3>Sign-Up Complete!</h3>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just whitespace changes?

request.write(claim.describe(env).encode('utf-8'))
request.finish()

def signup_failed(request, reason, customer, mailer):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The signature here doesn't match the caller. Line 149 doesn't pass the request in (and reason will be the first argument anyway). But it doesn't look like request is actually used - though perhaps it ought to be.

@@ -534,6 +535,8 @@ spec:
- 's4-subscription-manager'
- '--domain'
- '$(S4_DOMAIN)'
- '--cross-domain'
- '$(CROSS_DOMAIN)'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fwiw the only reason the parameter and its value are split into separate strings here is that I was just learning about how kubernetes env var interpolation works when I wrote this section. I wasn't sure it was allowed to interpolate into a string like --cross-domain=$(CROSS_DOMAIN) but as you can see above that style does work and I've used it elsewhere.

Doesn't really make any difference, just explaining why there are two different styles in this file.

Copy link
Contributor

@exarkun exarkun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, thank you. A number of very minor comments left inline. When they are addressed I think this should be ready for merge.

'support@leastauthority.com',
"A sign-up failed for <%s>." % (customer.email,),
headers,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Four space indentation for all Python code, please. :) Trailing newline at the end of the file is nice too.

.gitignore Outdated
# env file
.env

.DS_Store
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding this ignore. Can you also delete the .DS_Store files that were added?

.gitignore Outdated
@@ -26,3 +26,8 @@ telepresence.log

# distutils gunk
leastauthority.com.egg-info/

# env file
.env
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it expected that folks will have a .env file around? Is this where env-cmd takes its values from? Or is there another tool that's reading this file to initialize environment variables for local/development deployments of the backend?

@@ -1,90 +1,91 @@
apiVersion: ENC[AES256_GCM,data:17o=,iv:DqkDV/AR/NcKNDVPHKj4lyGxIrvcR5p3zYKlHPZtZRg=,tag:d/SllcsYkK7NegeTph3hKg==,type:str]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'll have to re-edit this file starting from current master. This file got changed in master meanwhile and the merge story for sops isn't very good (actually, there isn't really one). And I'll also have to make similar edits to the production secrets file to add the correct cross domain for production deployment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I merged master onto this branch, but this file still has different data.

@@ -8,14 +8,15 @@
from twisted.python.filepath import FilePath

from lae_site.handlers.web import JinjaHandler
from lae_site.handlers.submit_subscription import SubmitSubscriptionHandler
# TODO: Rename all handlers teh same way for consistency
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo teh

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this TODO is actually done, so will remove the comment

try:
return self._stripe.create(
authorization_token=stripe_authorization_token,
plan_id=PLAN_ID,
email=user_email,
)
except stripe.CardError as e:
# Always return 402 on card errors
request.setResponseCode(402)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can get a symbolic constant for 402 from twisted.web.http: PAYMENT_REQUIRED

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh cool stuff!

traceback.format_exc(100), e,
details=e.message.encode("utf-8"),
email_subject="Stripe Card error ({})".format(user_email),
notes=note,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Four space indents here and in the other exception handling blocks below, too.

email_subject="Stripe API error ({})".format(user_email),
traceback.format_exc(100), e,
details="Our payment processor is temporarily unavailable,"+
" please try again in\ a few moments.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can rely on compile-time literal string concatenation here.

(
    "foo"
    "bar"
)

is the same as

(
     "foo" +
     "bar"
)

except that the former is evaluated at compile time and the latter at runtime.

email_subject="Stripe Invalid Request error ({})".format(user_email),
traceback.format_exc(100), e,
details="Our payment processor is temporarily unavailable,"+
" please try again in\ a few moments.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

trace \ in this string

@@ -23,4 +23,4 @@ def render_GET(self, request):
S4_SIGNUP_STYLE_COOKIE,
request.args.get(b"style", [b"email"])[0]
)
return redirectTo(b"/s4-subscription-form", request)
return request
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. What does this do now?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should return the request instead of redirecting to s4-subscription-form with it

except RenderErrorDetailsForBrowser as e:
tmpl = env.get_template('s4-subscription-form.html')
return tmpl.render({"errorblock": e.details}).encode('utf-8', 'replace')
return e.details

# Initiate the provisioning service
subscription = customer.subscriptions.data[0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, the cookie-based signup-style selection logic that starts on the next line no longer works. Signup is always via email even if the cookie is set to wormhole. Do you have any idea about why this might be? Something related to CORS?

@exarkun exarkun merged commit d745de6 into master Sep 13, 2017
@exarkun exarkun deleted the subscription_form_edits branch September 13, 2017 14:02
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants