changes required ... @TODO: Finish identity federation with views

legacy
Steve L. Nyemba 8 years ago
parent 384c4e3aa1
commit ad400e6646

100
.gitignore vendored

@ -1,94 +1,6 @@
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
# Translations
*.mo
*.pot
# Django stuff:
*.log
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# ---> Android
# Built application files
*.apk
*.ap_
# Files for the Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
sandbox
*.pyc
*.swp
*.swo
.gitignore
config.json

@ -14,5 +14,15 @@ start(){
stop(){
ps -eo pid,command |grep python |grep $PWD |grep -E "^ {0,}[0-9]+" -o |xargs kill -9
}
check(){
pid=`ps -eo pid,command |grep python |grep $PWD |grep -E "^ {0,}[0-9]+" -o`
if [ "$pid" ]; then
echo "*** Online $pid"
else
echo "*** Offline"
fi
}
status(){
check
}
$1

@ -1,5 +1,10 @@
"""
This class is designed to handle Clients
This class is designed to handle Customers in coordination with stripes.
Identity Federation
A user with several emails should not have to pay for a service more than once because she has several email/cloud accounts.
We have therefore decided to tie several emails to a stripe customer identity
"""
import stripe
from couchdbkit import Server, Document
@ -23,27 +28,47 @@ class User:
"""
This function creates a stripe customer, and saves a copy with us for internal use
We use couchdb as a cache of sorts
"""
@param uid customer's email
@param plans list of plans the user is subscribing
"""
def getId(self,uid):
r = self.db.view('federation/ids',key=uid)
if r.count() > 0 :
r = r.first()
return r['value']
else:
None
def init (self,uid,plans):
customer = {}
if self.db.doc_exist(uid) :
self.user = self.db.get(uid)
id = self.getId(uid)
if id is not None:
self.user = self.db.get(id)
# if self.db.doc_exist(uid) :
# self.user = self.db.get(uid)
if self.stripeToken is not None:
if 'sources' not in self.user or self.user['sources'] is None:
#@TODO: get the appropriate id
customer = stripe.Customer.retrieve(self.user['id'])
customer.source=self.stripeToken
customer.save()
# self.hasPlan(uid,plan)
has_plan = True
if self.user is None and plans and stripe :
#
# First time customer, register them and sign them up for the first plan
#
customer['source'] = str(self.stripeToken)
customer['sources'] = str(self.stripeToken)
customer = self.stripe.Customer.create(
source=self.stripeToken,
email=uid
) ;
has_plan = False
id = customer['id']
self.user = {"_id":uid,"id":id}
self.user = {"_id":uid,"id":id,"source":self.stripeToken}
else:
#
# The user exists but let's see if the user is subscribed to this plan
@ -52,7 +77,10 @@ class User:
self.user = self.db.get(uid) ;
id = self.user['id']
#
# If this user's isn't already subscribed we should subscribe her
# We perform a set operation to determine if she is alread susbscribed
#
lsub = self.subscriptions()
lplans = [str(item['plan']['id']) for item in lsub.data if item.ended_at in [None,""]]
x_plans = [item['id'] for item in plans]
@ -62,7 +90,9 @@ class User:
x = list(set(x_plans) - set(lplans))
plans = [ item for item in plans if item.id in x]
else:
#
# In case the user doesn't have any plans with us
#
has_plan = False
if has_plan == False :
@ -93,15 +123,28 @@ class User:
def subscribe(self,id,plans):
r = []
for plan in plans:
x = self.stripe.Subscription.create(
customer=id,
plan=plan['id']
) ;
if self.stripeToken is None:
sub = self.stripe.Subscription.create(
customer=id,
plan=plan['id']
) ;
else:
customer = stripe.Customer.retrieve(id)
self.user['sources'] = self.cast(customer.sources)
sub = self.stripe.Subscription.create(
customer=id,
plan=plan['id'],
source=self.stripeToken
) ;
r.append(sub)
#
# We need to create an invoiced item out of this plan
# We will attach it later to an invoice ...
#
r.append(x)
#r.append(x)
return r
"""
This function will save card information
@ -122,7 +165,9 @@ class User:
self.db.save_doc(user) ;
self.user = user
def invoice(self,uid,plans,iid):
#
# Creating an invoice for this user
def invoice(self,uid,sid):
self.user = self.db.get(uid)
id = self.user['id']
r = [ stripe.InvoiceItem.create(customer=id,amount=item['amount'],currency=item['currency'],description=item['statement_descriptor'],subscription=item['subscription'],invoice=iid) for item in plans]

@ -45,19 +45,32 @@ def subscribe(app_name):
#
# The name is the full name of the service
#
resp = "0"
if 'stripeToken' in request.form :
stripeToken = request.form['stripeToken']
uid = request.form['stripeEmail']
tokenType = request.form['stripeTokenType']
amount = request.form['amount']
key = request.form['plan']
key = request.headers['key']
uid = request.headers['uid']
else:
key = request.headers['key']
uid = request.headers['uid']
stripeToken = None
plans = stripe.Plan.list().data
plan = [item for item in plans if item.id == key]
resp = "0"
couch_handler = Couchdb(uri=CONFIG['couchdb']['uri'],dbname=app_name,uid=uid)
DB = couch_handler.dbase
handler = Domain.User(DB,stripe,stripeToken) ;
if plan :
couch_handler = Couchdb(uri=CONFIG['couchdb']['uri'],dbname=app_name,uid=uid)
DB = couch_handler.dbase
handler = Domain.User(DB,stripe) ;
handler.init(uid,plan)
resp = plan[0].id
return resp
resp = plan[0].id
return ('done',204)
"""
This function returns the meta data about a given plan or set of plans for a given application
@resource app_name application identifier

@ -2,6 +2,7 @@
<meta http-equiv="cache-control" content="no-cache">
<meta name="viewport" content="width=device-width, initial-scale=1,maximum-scale=1">
<link rel="shortcut icon" href="/static/img/logo-0.png">
<title style="text-transform: capitalize">{{app_name.replace('-',' ')}}</title>
<style>
body{
font-family:sans-serif;
@ -87,12 +88,12 @@
<div class="small">Available Plans, Charges will apply after trial period</div>
</td>
</tr>
<tr class="default">
<tr class="default" valign="top">
{% for item in plans%}
{% if loop.index0 > 0 %}
<td align="center" style="border-left:1px solid #CAD5E0">
{% else %}
<td align="center">
<td align="center" >
{% endif %}
<div class="medium-caption">{{ item.name.replace('-',' ') }}</div>
@ -106,19 +107,23 @@
</div>
<br>
<div>
<form action="/pay/{{app_name|safe}}" method="POST">
<form action="/subscribe/{{app_name|safe}}" method="POST">
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="{{apikey|safe}}"
data-email="{{uid|safe}}"
data-amount={{item.amount|safe}}
data-name="The Phi Technology LLC"
data-name="{{item.metadata.info}}"
data-description=""
data-image="https://s3.amazonaws.com/stripe-uploads/acct_15kiA1EUWsmgY81Amerchant-icon-1443577505909-the-phi-logo.png"
data-label="Signup Now"
data-image="https://s3.amazonaws.com/stripe-uploads/acct_15kiA1EUWsmgY81Amerchant-icon-1493912370912-logo-0.png"
data-locale="auto">
</script>
<input type="hidden" name="amount" value="{{item.amount|safe}}"/>
<input type="hidden" name="plan" value="{{item.id|safe}}"/>
</form>
</div>
{% else %}

Loading…
Cancel
Save