Merge remote-tracking branch 'remotes/origin/stripe-integration' into add-device
commit
13095c34b6
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "daaf58243bb30ef012d7013696ccfce15271d61670ef9bd6cebe9d7ffadefd6e"
|
||||
"sha256": "3e2ce31477884f9983a6eb644183790f946eafc0b88a068507a8e42512c86d70"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
|
@ -16,100 +16,6 @@
|
|||
]
|
||||
},
|
||||
"default": {
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
|
||||
"sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"
|
||||
],
|
||||
"version": "==7.0"
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
"sha256:2271c0070dbcb5275fad4a82e29f23ab92682dc45f9dfbc22c02ba9b9322ce48",
|
||||
"sha256:a080b744b7e345ccfcbc77954861cb05b3c63786e93f2b3875e0913d44b43f05"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.0.2"
|
||||
},
|
||||
"itsdangerous": {
|
||||
"hashes": [
|
||||
"sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19",
|
||||
"sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"
|
||||
],
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"jinja2": {
|
||||
"hashes": [
|
||||
"sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd",
|
||||
"sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4"
|
||||
],
|
||||
"version": "==2.10"
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
"sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432",
|
||||
"sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b",
|
||||
"sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9",
|
||||
"sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af",
|
||||
"sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834",
|
||||
"sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd",
|
||||
"sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d",
|
||||
"sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7",
|
||||
"sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b",
|
||||
"sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3",
|
||||
"sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c",
|
||||
"sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2",
|
||||
"sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7",
|
||||
"sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36",
|
||||
"sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1",
|
||||
"sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e",
|
||||
"sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1",
|
||||
"sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c",
|
||||
"sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856",
|
||||
"sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550",
|
||||
"sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492",
|
||||
"sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672",
|
||||
"sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401",
|
||||
"sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6",
|
||||
"sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6",
|
||||
"sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c",
|
||||
"sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd",
|
||||
"sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1"
|
||||
],
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"schematics": {
|
||||
"hashes": [
|
||||
"sha256:8fcc6182606fd0b24410a1dbb066d9bbddbe8da9c9509f47b743495706239283",
|
||||
"sha256:a40b20635c0e43d18d3aff76220f6cd95ea4decb3f37765e49529b17d81b0439"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.1.0"
|
||||
},
|
||||
"uwsgi": {
|
||||
"hashes": [
|
||||
"sha256:4972ac538800fb2d421027f49b4a1869b66048839507ccf0aa2fda792d99f583"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.0.18"
|
||||
},
|
||||
"werkzeug": {
|
||||
"hashes": [
|
||||
"sha256:c3fd7a7d41976d9f44db327260e263132466836cef6f91512889ed60ad26557c",
|
||||
"sha256:d5da73735293558eb1651ee2fddc4d0dedcfa06538b8813a2e20011583c9e49b"
|
||||
],
|
||||
"version": "==0.14.1"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
"behave": {
|
||||
"hashes": [
|
||||
"sha256:b9662327aa53294c1351b0a9c369093ccec1d21026f050c3bd9b3e5cccf81a86",
|
||||
"sha256:ebda1a6c9e5bfe95c5f9f0a2794e01c7098b3dde86c10a95d8621c5907ff6f1c"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.2.6"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7",
|
||||
|
@ -133,10 +39,10 @@
|
|||
},
|
||||
"deprecated": {
|
||||
"hashes": [
|
||||
"sha256:8bfeba6e630abf42b5d111b68a05f7fe3d6de7004391b3cd614947594f87a4ff",
|
||||
"sha256:b784e0ca85a8c1e694d77e545c10827bd99772392e79d5f5442e761515a1246e"
|
||||
"sha256:2f293eb0eee34b1fcf3da530fe8fc4b0d71d43ddc2dc78e2ffb444b6c0868557",
|
||||
"sha256:749f6cdcfbdc3f79258f8154bad43fced95adc632c337675d0385959895894bc"
|
||||
],
|
||||
"version": "==1.2.4"
|
||||
"version": "==1.2.5"
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
|
@ -167,58 +73,38 @@
|
|||
],
|
||||
"version": "==2.10"
|
||||
},
|
||||
"jsonschema": {
|
||||
"hashes": [
|
||||
"sha256:000e68abd33c972a5248544925a0cae7d1125f9bf6c58280d37546b946769a08",
|
||||
"sha256:6ff5f3180870836cae40f06fa10419f557208175f13ad7bc26caa77beb1f6e02"
|
||||
],
|
||||
"version": "==2.6.0"
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
"sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432",
|
||||
"sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b",
|
||||
"sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9",
|
||||
"sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af",
|
||||
"sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834",
|
||||
"sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd",
|
||||
"sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d",
|
||||
"sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7",
|
||||
"sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b",
|
||||
"sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3",
|
||||
"sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c",
|
||||
"sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2",
|
||||
"sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7",
|
||||
"sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36",
|
||||
"sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1",
|
||||
"sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e",
|
||||
"sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1",
|
||||
"sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c",
|
||||
"sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856",
|
||||
"sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550",
|
||||
"sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492",
|
||||
"sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672",
|
||||
"sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401",
|
||||
"sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6",
|
||||
"sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6",
|
||||
"sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c",
|
||||
"sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd",
|
||||
"sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1"
|
||||
"sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
|
||||
"sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161",
|
||||
"sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235",
|
||||
"sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5",
|
||||
"sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff",
|
||||
"sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b",
|
||||
"sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1",
|
||||
"sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e",
|
||||
"sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183",
|
||||
"sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66",
|
||||
"sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1",
|
||||
"sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1",
|
||||
"sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
|
||||
"sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b",
|
||||
"sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905",
|
||||
"sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735",
|
||||
"sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d",
|
||||
"sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e",
|
||||
"sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d",
|
||||
"sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c",
|
||||
"sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21",
|
||||
"sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2",
|
||||
"sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5",
|
||||
"sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b",
|
||||
"sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6",
|
||||
"sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f",
|
||||
"sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f",
|
||||
"sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"
|
||||
],
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"parse": {
|
||||
"hashes": [
|
||||
"sha256:870dd675c1ee8951db3e29b81ebe44fd131e3eb8c03a79483a58ea574f3145c2"
|
||||
],
|
||||
"version": "==1.11.1"
|
||||
},
|
||||
"parse-type": {
|
||||
"hashes": [
|
||||
"sha256:6e906a66f340252e4c324914a60d417d33a4bea01292ea9bbf68b4fc123be8c9",
|
||||
"sha256:f596bdc75d3dd93036fbfe3d04127da9f6df0c26c36e01e76da85adef4336b3c"
|
||||
],
|
||||
"version": "==0.4.2"
|
||||
"version": "==1.1.1"
|
||||
},
|
||||
"passlib": {
|
||||
"hashes": [
|
||||
|
@ -273,7 +159,6 @@
|
|||
"sha256:6b672c02fdf7470df9674ab82263841ce8333fb143f32f021f6cb26f0e512420",
|
||||
"sha256:8ffaa0a53da57e89de14ced7185ac746227a8894dbd5a3c718bf05ddbd1d56cd"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.9.0"
|
||||
},
|
||||
"pyjwt": {
|
||||
|
@ -323,11 +208,12 @@
|
|||
],
|
||||
"version": "==1.24.1"
|
||||
},
|
||||
"validator-collection": {
|
||||
"uwsgi": {
|
||||
"hashes": [
|
||||
"sha256:e8ddec6d301bd3be40cacb9d4f9f85573bc003e3e17a66ba7267ef46b9a8e3d2"
|
||||
"sha256:4972ac538800fb2d421027f49b4a1869b66048839507ccf0aa2fda792d99f583"
|
||||
],
|
||||
"version": "==1.3.2"
|
||||
"index": "pypi",
|
||||
"version": "==2.0.18"
|
||||
},
|
||||
"werkzeug": {
|
||||
"hashes": [
|
||||
|
@ -342,5 +228,42 @@
|
|||
],
|
||||
"version": "==1.11.1"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
"behave": {
|
||||
"hashes": [
|
||||
"sha256:b9662327aa53294c1351b0a9c369093ccec1d21026f050c3bd9b3e5cccf81a86",
|
||||
"sha256:ebda1a6c9e5bfe95c5f9f0a2794e01c7098b3dde86c10a95d8621c5907ff6f1c"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.2.6"
|
||||
},
|
||||
"parse": {
|
||||
"hashes": [
|
||||
"sha256:870dd675c1ee8951db3e29b81ebe44fd131e3eb8c03a79483a58ea574f3145c2"
|
||||
],
|
||||
"version": "==1.11.1"
|
||||
},
|
||||
"parse-type": {
|
||||
"hashes": [
|
||||
"sha256:6e906a66f340252e4c324914a60d417d33a4bea01292ea9bbf68b4fc123be8c9",
|
||||
"sha256:f596bdc75d3dd93036fbfe3d04127da9f6df0c26c36e01e76da85adef4336b3c"
|
||||
],
|
||||
"version": "==0.4.2"
|
||||
},
|
||||
"pyhamcrest": {
|
||||
"hashes": [
|
||||
"sha256:6b672c02fdf7470df9674ab82263841ce8333fb143f32f021f6cb26f0e512420",
|
||||
"sha256:8ffaa0a53da57e89de14ced7185ac746227a8894dbd5a3c718bf05ddbd1d56cd"
|
||||
],
|
||||
"version": "==1.9.0"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
|
||||
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
|
||||
],
|
||||
"version": "==1.12.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,8 +8,9 @@ from .endpoints.account_preferences import AccountPreferencesEndpoint
|
|||
from .endpoints.device import DeviceEndpoint
|
||||
from .endpoints.device_count import DeviceCountEndpoint
|
||||
from .endpoints.geography import GeographyEndpoint
|
||||
from .endpoints.skills import SkillsEndpoint
|
||||
from .endpoints.membership import MembershipEndpoint
|
||||
from .endpoints.skill_settings import SkillSettingsEndpoint
|
||||
from .endpoints.skills import SkillsEndpoint
|
||||
from .endpoints.voice_endpoint import VoiceEndpoint
|
||||
from .endpoints.wake_word_endpoint import WakeWordEndpoint
|
||||
|
||||
|
@ -25,7 +26,7 @@ acct.register_blueprint(selene_api)
|
|||
acct.add_url_rule(
|
||||
'/api/account',
|
||||
view_func=AccountEndpoint.as_view('account_api'),
|
||||
methods=['GET', 'POST']
|
||||
methods=['GET', 'POST', 'PATCH']
|
||||
)
|
||||
acct.add_url_rule(
|
||||
'/api/agreement/<string:agreement_type>',
|
||||
|
@ -90,3 +91,10 @@ acct.add_url_rule(
|
|||
view_func=geography_endpoint,
|
||||
methods=['GET']
|
||||
)
|
||||
|
||||
membership_endpoint = MembershipEndpoint.as_view('membership_endpoint')
|
||||
acct.add_url_rule(
|
||||
'/api/memberships',
|
||||
view_func=membership_endpoint,
|
||||
methods=['GET']
|
||||
)
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
from http import HTTPStatus
|
||||
|
||||
from selene.api import SeleneEndpoint
|
||||
from selene.data.account import MembershipRepository
|
||||
from selene.util.db import get_db_connection
|
||||
|
||||
|
||||
class MembershipEndpoint(SeleneEndpoint):
|
||||
def get(self):
|
||||
with get_db_connection(self.config['DB_CONNECTION_POOL']) as db:
|
||||
membership_repository = MembershipRepository(db)
|
||||
membership_types = membership_repository.get_membership_types()
|
||||
|
||||
for membership_type in membership_types:
|
||||
membership_type.rate = float(membership_type.rate)
|
||||
return membership_types, HTTPStatus.OK
|
|
@ -2,7 +2,7 @@ from datetime import date
|
|||
|
||||
from behave import given, then, when
|
||||
from flask import json
|
||||
from hamcrest import assert_that, equal_to, is_in, none, not_none
|
||||
from hamcrest import assert_that, equal_to, is_in, none, not_none, starts_with
|
||||
|
||||
from selene.data.account import AccountRepository, PRIVACY_POLICY, TERMS_OF_USE
|
||||
from selene.util.db import get_db_connection
|
||||
|
@ -39,7 +39,7 @@ def change_membership_option(context):
|
|||
context.new_account_request['support'].update(
|
||||
membership='Monthly Membership',
|
||||
paymentMethod='Stripe',
|
||||
paymentAccountId='barstripe'
|
||||
paymentToken='tok_visa'
|
||||
)
|
||||
|
||||
|
||||
|
@ -72,7 +72,7 @@ def check_db_for_account(context, membership_option):
|
|||
assert_that(account.membership.type, equal_to('Monthly Membership'))
|
||||
assert_that(
|
||||
account.membership.payment_account_id,
|
||||
equal_to('barstripe')
|
||||
starts_with('cus')
|
||||
)
|
||||
elif membership_option == 'without a membership':
|
||||
assert_that(account.membership, none())
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
Feature: Test the API call to update a membership
|
||||
|
||||
Scenario: user with free account opts into a membership
|
||||
Given a user with a free account
|
||||
When a monthly membership is added
|
|
@ -12,6 +12,7 @@ flask = "*"
|
|||
requests = "*"
|
||||
SpeechRecognition = "*"
|
||||
uwsgi = "*"
|
||||
stripe = "*"
|
||||
|
||||
[requires]
|
||||
python_version = "3.7"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "5fa825684354d0d9bb2336a9ecdce746401ea0d5c3f1e96b5f508f8a5b237c4c"
|
||||
"sha256": "334f43f32cee22ca9973853301b232a9e302331dacc5b00f348c93637f89cae3"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
|
@ -114,6 +114,14 @@
|
|||
"index": "pypi",
|
||||
"version": "==3.8.1"
|
||||
},
|
||||
"stripe": {
|
||||
"hashes": [
|
||||
"sha256:170f76f2502888debf02da580138c840497b9359876ca3838f4692f2f02c9110",
|
||||
"sha256:35441857c8d6969a3f319f0f3cb0ddf853fe36ed451b3b711bc0295241c38444"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.21.0"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39",
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import json
|
||||
from dataclasses import asdict
|
||||
from http import HTTPStatus
|
||||
|
||||
from schematics import Model
|
||||
|
|
|
@ -43,7 +43,7 @@ def get_device_subscription(context):
|
|||
access_token = login['accessToken']
|
||||
headers=dict(Authorization='Bearer {token}'.format(token=access_token))
|
||||
with get_db_connection(context.client_config['DB_CONNECTION_POOL']) as db:
|
||||
AccountRepository(db)._add_membership(context.account.id, membership)
|
||||
AccountRepository(db).add_membership(context.account.id, membership)
|
||||
context.subscription_response = context.client.get(
|
||||
'/v1/device/{uuid}/subscription'.format(uuid=device_id),
|
||||
headers=headers
|
||||
|
|
|
@ -6,10 +6,10 @@ name = "pypi"
|
|||
[packages]
|
||||
flask = "*"
|
||||
certifi = "*"
|
||||
selene = {editable = true,path = "./../../shared"}
|
||||
uwsgi = "*"
|
||||
|
||||
[dev-packages]
|
||||
selene = {editable = true,path = "./../../shared"}
|
||||
behave = "*"
|
||||
pyhamcrest = "*"
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "e27bc9018c42543c8594ffade1899d7d7c9cef2117f4c48462b0971310caeb0f"
|
||||
"sha256": "8a88efc755cb5bfcda2c6e9db57fb62a506e475386cdcda3da69435427d0a2fe"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
|
@ -16,100 +16,6 @@
|
|||
]
|
||||
},
|
||||
"default": {
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7",
|
||||
"sha256:993f830721089fef441cdfeb4b2c8c9df86f0c63239f06bd025a76a7daddb033"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2018.11.29"
|
||||
},
|
||||
"click": {
|
||||
"hashes": [
|
||||
"sha256:2335065e6395b9e67ca716de5f7526736bfa6ceead690adf616d925bdc622b13",
|
||||
"sha256:5b94b49521f6456670fdb30cd82a4eca9412788a93fa6dd6df72c94d5a8ff2d7"
|
||||
],
|
||||
"version": "==7.0"
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
"sha256:2271c0070dbcb5275fad4a82e29f23ab92682dc45f9dfbc22c02ba9b9322ce48",
|
||||
"sha256:a080b744b7e345ccfcbc77954861cb05b3c63786e93f2b3875e0913d44b43f05"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.0.2"
|
||||
},
|
||||
"itsdangerous": {
|
||||
"hashes": [
|
||||
"sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19",
|
||||
"sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"
|
||||
],
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"jinja2": {
|
||||
"hashes": [
|
||||
"sha256:74c935a1b8bb9a3947c50a54766a969d4846290e1e788ea44c1392163723c3bd",
|
||||
"sha256:f84be1bb0040caca4cea721fcbbbbd61f9be9464ca236387158b0feea01914a4"
|
||||
],
|
||||
"version": "==2.10"
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
"sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432",
|
||||
"sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b",
|
||||
"sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9",
|
||||
"sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af",
|
||||
"sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834",
|
||||
"sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd",
|
||||
"sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d",
|
||||
"sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7",
|
||||
"sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b",
|
||||
"sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3",
|
||||
"sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c",
|
||||
"sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2",
|
||||
"sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7",
|
||||
"sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36",
|
||||
"sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1",
|
||||
"sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e",
|
||||
"sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1",
|
||||
"sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c",
|
||||
"sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856",
|
||||
"sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550",
|
||||
"sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492",
|
||||
"sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672",
|
||||
"sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401",
|
||||
"sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6",
|
||||
"sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6",
|
||||
"sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c",
|
||||
"sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd",
|
||||
"sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1"
|
||||
],
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"uwsgi": {
|
||||
"hashes": [
|
||||
"sha256:4972ac538800fb2d421027f49b4a1869b66048839507ccf0aa2fda792d99f583"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.0.18"
|
||||
},
|
||||
"werkzeug": {
|
||||
"hashes": [
|
||||
"sha256:c3fd7a7d41976d9f44db327260e263132466836cef6f91512889ed60ad26557c",
|
||||
"sha256:d5da73735293558eb1651ee2fddc4d0dedcfa06538b8813a2e20011583c9e49b"
|
||||
],
|
||||
"version": "==0.14.1"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
"behave": {
|
||||
"hashes": [
|
||||
"sha256:b9662327aa53294c1351b0a9c369093ccec1d21026f050c3bd9b3e5cccf81a86",
|
||||
"sha256:ebda1a6c9e5bfe95c5f9f0a2794e01c7098b3dde86c10a95d8621c5907ff6f1c"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.2.6"
|
||||
},
|
||||
"certifi": {
|
||||
"hashes": [
|
||||
"sha256:47f9c83ef4c0c621eaef743f133f09fa8a74a9b75f037e8624f83bd1b6626cb7",
|
||||
|
@ -134,10 +40,10 @@
|
|||
},
|
||||
"deprecated": {
|
||||
"hashes": [
|
||||
"sha256:8bfeba6e630abf42b5d111b68a05f7fe3d6de7004391b3cd614947594f87a4ff",
|
||||
"sha256:b784e0ca85a8c1e694d77e545c10827bd99772392e79d5f5442e761515a1246e"
|
||||
"sha256:2f293eb0eee34b1fcf3da530fe8fc4b0d71d43ddc2dc78e2ffb444b6c0868557",
|
||||
"sha256:749f6cdcfbdc3f79258f8154bad43fced95adc632c337675d0385959895894bc"
|
||||
],
|
||||
"version": "==1.2.4"
|
||||
"version": "==1.2.5"
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
|
@ -170,49 +76,36 @@
|
|||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
"sha256:048ef924c1623740e70204aa7143ec592504045ae4429b59c30054cb31e3c432",
|
||||
"sha256:130f844e7f5bdd8e9f3f42e7102ef1d49b2e6fdf0d7526df3f87281a532d8c8b",
|
||||
"sha256:19f637c2ac5ae9da8bfd98cef74d64b7e1bb8a63038a3505cd182c3fac5eb4d9",
|
||||
"sha256:1b8a7a87ad1b92bd887568ce54b23565f3fd7018c4180136e1cf412b405a47af",
|
||||
"sha256:1c25694ca680b6919de53a4bb3bdd0602beafc63ff001fea2f2fc16ec3a11834",
|
||||
"sha256:1f19ef5d3908110e1e891deefb5586aae1b49a7440db952454b4e281b41620cd",
|
||||
"sha256:1fa6058938190ebe8290e5cae6c351e14e7bb44505c4a7624555ce57fbbeba0d",
|
||||
"sha256:31cbb1359e8c25f9f48e156e59e2eaad51cd5242c05ed18a8de6dbe85184e4b7",
|
||||
"sha256:3e835d8841ae7863f64e40e19477f7eb398674da6a47f09871673742531e6f4b",
|
||||
"sha256:4e97332c9ce444b0c2c38dd22ddc61c743eb208d916e4265a2a3b575bdccb1d3",
|
||||
"sha256:525396ee324ee2da82919f2ee9c9e73b012f23e7640131dd1b53a90206a0f09c",
|
||||
"sha256:52b07fbc32032c21ad4ab060fec137b76eb804c4b9a1c7c7dc562549306afad2",
|
||||
"sha256:52ccb45e77a1085ec5461cde794e1aa037df79f473cbc69b974e73940655c8d7",
|
||||
"sha256:5c3fbebd7de20ce93103cb3183b47671f2885307df4a17a0ad56a1dd51273d36",
|
||||
"sha256:5e5851969aea17660e55f6a3be00037a25b96a9b44d2083651812c99d53b14d1",
|
||||
"sha256:5edfa27b2d3eefa2210fb2f5d539fbed81722b49f083b2c6566455eb7422fd7e",
|
||||
"sha256:7d263e5770efddf465a9e31b78362d84d015cc894ca2c131901a4445eaa61ee1",
|
||||
"sha256:83381342bfc22b3c8c06f2dd93a505413888694302de25add756254beee8449c",
|
||||
"sha256:857eebb2c1dc60e4219ec8e98dfa19553dae33608237e107db9c6078b1167856",
|
||||
"sha256:98e439297f78fca3a6169fd330fbe88d78b3bb72f967ad9961bcac0d7fdd1550",
|
||||
"sha256:bf54103892a83c64db58125b3f2a43df6d2cb2d28889f14c78519394feb41492",
|
||||
"sha256:d9ac82be533394d341b41d78aca7ed0e0f4ba5a2231602e2f05aa87f25c51672",
|
||||
"sha256:e982fe07ede9fada6ff6705af70514a52beb1b2c3d25d4e873e82114cf3c5401",
|
||||
"sha256:edce2ea7f3dfc981c4ddc97add8a61381d9642dc3273737e756517cc03e84dd6",
|
||||
"sha256:efdc45ef1afc238db84cb4963aa689c0408912a0239b0721cb172b4016eb31d6",
|
||||
"sha256:f137c02498f8b935892d5c0172560d7ab54bc45039de8805075e19079c639a9c",
|
||||
"sha256:f82e347a72f955b7017a39708a3667f106e6ad4d10b25f237396a7115d8ed5fd",
|
||||
"sha256:fb7c206e01ad85ce57feeaaa0bf784b97fa3cad0d4a5737bc5295785f5c613a1"
|
||||
"sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
|
||||
"sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161",
|
||||
"sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235",
|
||||
"sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5",
|
||||
"sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff",
|
||||
"sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b",
|
||||
"sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1",
|
||||
"sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e",
|
||||
"sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183",
|
||||
"sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66",
|
||||
"sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1",
|
||||
"sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1",
|
||||
"sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
|
||||
"sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b",
|
||||
"sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905",
|
||||
"sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735",
|
||||
"sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d",
|
||||
"sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e",
|
||||
"sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d",
|
||||
"sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c",
|
||||
"sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21",
|
||||
"sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2",
|
||||
"sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5",
|
||||
"sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b",
|
||||
"sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6",
|
||||
"sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f",
|
||||
"sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f",
|
||||
"sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"
|
||||
],
|
||||
"version": "==1.1.0"
|
||||
},
|
||||
"parse": {
|
||||
"hashes": [
|
||||
"sha256:870dd675c1ee8951db3e29b81ebe44fd131e3eb8c03a79483a58ea574f3145c2"
|
||||
],
|
||||
"version": "==1.11.1"
|
||||
},
|
||||
"parse-type": {
|
||||
"hashes": [
|
||||
"sha256:6e906a66f340252e4c324914a60d417d33a4bea01292ea9bbf68b4fc123be8c9",
|
||||
"sha256:f596bdc75d3dd93036fbfe3d04127da9f6df0c26c36e01e76da85adef4336b3c"
|
||||
],
|
||||
"version": "==0.4.2"
|
||||
"version": "==1.1.1"
|
||||
},
|
||||
"passlib": {
|
||||
"hashes": [
|
||||
|
@ -267,7 +160,6 @@
|
|||
"sha256:6b672c02fdf7470df9674ab82263841ce8333fb143f32f021f6cb26f0e512420",
|
||||
"sha256:8ffaa0a53da57e89de14ced7185ac746227a8894dbd5a3c718bf05ddbd1d56cd"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.9.0"
|
||||
},
|
||||
"pyjwt": {
|
||||
|
@ -277,6 +169,13 @@
|
|||
],
|
||||
"version": "==1.7.1"
|
||||
},
|
||||
"redis": {
|
||||
"hashes": [
|
||||
"sha256:724932360d48e5407e8f82e405ab3650a36ed02c7e460d1e6fddf0f038422b54",
|
||||
"sha256:9b19425a38fd074eb5795ff2b0d9a55b46a44f91f5347995f27e3ad257a7d775"
|
||||
],
|
||||
"version": "==3.2.0"
|
||||
},
|
||||
"requests": {
|
||||
"hashes": [
|
||||
"sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e",
|
||||
|
@ -309,6 +208,13 @@
|
|||
],
|
||||
"version": "==1.24.1"
|
||||
},
|
||||
"uwsgi": {
|
||||
"hashes": [
|
||||
"sha256:4972ac538800fb2d421027f49b4a1869b66048839507ccf0aa2fda792d99f583"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.0.18"
|
||||
},
|
||||
"werkzeug": {
|
||||
"hashes": [
|
||||
"sha256:c3fd7a7d41976d9f44db327260e263132466836cef6f91512889ed60ad26557c",
|
||||
|
@ -322,5 +228,42 @@
|
|||
],
|
||||
"version": "==1.11.1"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
"behave": {
|
||||
"hashes": [
|
||||
"sha256:b9662327aa53294c1351b0a9c369093ccec1d21026f050c3bd9b3e5cccf81a86",
|
||||
"sha256:ebda1a6c9e5bfe95c5f9f0a2794e01c7098b3dde86c10a95d8621c5907ff6f1c"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.2.6"
|
||||
},
|
||||
"parse": {
|
||||
"hashes": [
|
||||
"sha256:870dd675c1ee8951db3e29b81ebe44fd131e3eb8c03a79483a58ea574f3145c2"
|
||||
],
|
||||
"version": "==1.11.1"
|
||||
},
|
||||
"parse-type": {
|
||||
"hashes": [
|
||||
"sha256:6e906a66f340252e4c324914a60d417d33a4bea01292ea9bbf68b4fc123be8c9",
|
||||
"sha256:f596bdc75d3dd93036fbfe3d04127da9f6df0c26c36e01e76da85adef4336b3c"
|
||||
],
|
||||
"version": "==0.4.2"
|
||||
},
|
||||
"pyhamcrest": {
|
||||
"hashes": [
|
||||
"sha256:6b672c02fdf7470df9674ab82263841ce8333fb143f32f021f6cb26f0e512420",
|
||||
"sha256:8ffaa0a53da57e89de14ced7185ac746227a8894dbd5a3c718bf05ddbd1d56cd"
|
||||
],
|
||||
"version": "==1.9.0"
|
||||
},
|
||||
"six": {
|
||||
"hashes": [
|
||||
"sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c",
|
||||
"sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"
|
||||
],
|
||||
"version": "==1.12.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
INSERT INTO
|
||||
account.membership (type, rate, rate_period)
|
||||
account.membership (type, rate, rate_period, stripe_plan)
|
||||
VALUES
|
||||
('Monthly Membership', 1.99, 'month'),
|
||||
('Yearly Membership', 19.99, 'year')
|
||||
('Monthly Membership', 1.99, 'month', 'monthly_premium'),
|
||||
('Yearly Membership', 19.99, 'year', 'mycroft_ai_premium_annual_1999')
|
||||
;
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
CREATE TABLE account.membership (
|
||||
id uuid PRIMARY KEY
|
||||
DEFAULT gen_random_uuid(),
|
||||
type membership_type_enum NOT NULL
|
||||
type membership_type_enum NOT NULL
|
||||
UNIQUE,
|
||||
rate NUMERIC NOT NULL,
|
||||
rate_period text NOT NULL,
|
||||
stripe_plan text NOT NULL,
|
||||
insert_ts TIMESTAMP NOT NULL
|
||||
DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
|
|
@ -11,6 +11,7 @@ passlib = "*"
|
|||
pyhamcrest = "*"
|
||||
schematics = "*"
|
||||
redis = "*"
|
||||
stripe = "*"
|
||||
|
||||
[dev-packages]
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "c0c1a9ec56002f00c9a50fc67aba1b0463d05323813944a244860fd69f49b75c"
|
||||
"sha256": "302bee79d7d85ce5050af796f262d7e1000ecf5be0353cdf565273cc1823785a"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
|
@ -32,10 +32,10 @@
|
|||
},
|
||||
"deprecated": {
|
||||
"hashes": [
|
||||
"sha256:8bfeba6e630abf42b5d111b68a05f7fe3d6de7004391b3cd614947594f87a4ff",
|
||||
"sha256:b784e0ca85a8c1e694d77e545c10827bd99772392e79d5f5442e761515a1246e"
|
||||
"sha256:2f293eb0eee34b1fcf3da530fe8fc4b0d71d43ddc2dc78e2ffb444b6c0868557",
|
||||
"sha256:749f6cdcfbdc3f79258f8154bad43fced95adc632c337675d0385959895894bc"
|
||||
],
|
||||
"version": "==1.2.4"
|
||||
"version": "==1.2.5"
|
||||
},
|
||||
"idna": {
|
||||
"hashes": [
|
||||
|
@ -124,6 +124,7 @@
|
|||
"sha256:502a824f31acdacb3a35b6690b5fbf0bc41d63a24a45c4004352b0242707598e",
|
||||
"sha256:7bf2a778576d825600030a110f3c0e3e8edc51dfaafe1c146e39a2027784957b"
|
||||
],
|
||||
"markers": "python_version >= '3.0'",
|
||||
"version": "==2.21.0"
|
||||
},
|
||||
"schematics": {
|
||||
|
@ -141,6 +142,14 @@
|
|||
],
|
||||
"version": "==1.12.0"
|
||||
},
|
||||
"stripe": {
|
||||
"hashes": [
|
||||
"sha256:170f76f2502888debf02da580138c840497b9359876ca3838f4692f2f02c9110",
|
||||
"sha256:35441857c8d6969a3f319f0f3cb0ddf853fe36ed451b3b711bc0295241c38444"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==2.21.0"
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:61bf29cada3fc2fbefad4fdf059ea4bd1b4a86d2b6d15e1c7c0b582b9752fe39",
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
"""API endpoint to return the a logged-in user's profile"""
|
||||
import os
|
||||
from dataclasses import asdict
|
||||
from datetime import date, datetime, timedelta
|
||||
from http import HTTPStatus
|
||||
|
||||
import stripe
|
||||
from flask import json, jsonify
|
||||
from schematics import Model
|
||||
from schematics.exceptions import ValidationError
|
||||
|
@ -14,14 +16,17 @@ from selene.data.account import (
|
|||
AccountRepository,
|
||||
AccountMembership,
|
||||
PRIVACY_POLICY,
|
||||
TERMS_OF_USE
|
||||
)
|
||||
TERMS_OF_USE,
|
||||
MembershipRepository)
|
||||
from selene.util.db import get_db_connection
|
||||
from ..base_endpoint import SeleneEndpoint
|
||||
|
||||
MONTHLY_MEMBERSHIP = 'Monthly Membership'
|
||||
YEARLY_MEMBERSHIP = 'Yearly Membership'
|
||||
NO_MEMBERSHIP = 'Maybe Later'
|
||||
STRIPE_PAYMENT = 'Stripe'
|
||||
|
||||
stripe.api_key = os.environ['STRIPE_PRIVATE_KEY']
|
||||
|
||||
|
||||
def agreement_accepted(value):
|
||||
|
@ -55,16 +60,24 @@ class Support(Model):
|
|||
required=True,
|
||||
choices=(MONTHLY_MEMBERSHIP, YEARLY_MEMBERSHIP, NO_MEMBERSHIP)
|
||||
)
|
||||
payment_method = StringType()
|
||||
payment_account_id = StringType()
|
||||
payment_method = StringType(choices=[STRIPE_PAYMENT])
|
||||
payment_token = StringType()
|
||||
|
||||
def validate_payment_account_id(self, data, value):
|
||||
if data['membership'] != NO_MEMBERSHIP:
|
||||
if not data['payment_account_id']:
|
||||
raise ValidationError(
|
||||
'Membership requires a payment account ID'
|
||||
)
|
||||
return value
|
||||
|
||||
class AddMembership(Model):
|
||||
membership = StringType(
|
||||
required=True,
|
||||
choices=(MONTHLY_MEMBERSHIP, YEARLY_MEMBERSHIP, NO_MEMBERSHIP)
|
||||
)
|
||||
payment_method = StringType(required=True, choices=[STRIPE_PAYMENT])
|
||||
payment_token = StringType(required=True)
|
||||
|
||||
|
||||
class UpdateMembership(Model):
|
||||
membership = StringType(
|
||||
required=True,
|
||||
choices=(MONTHLY_MEMBERSHIP, YEARLY_MEMBERSHIP, NO_MEMBERSHIP)
|
||||
)
|
||||
|
||||
|
||||
class AddAccountRequest(Model):
|
||||
|
@ -138,6 +151,11 @@ class AccountEndpoint(SeleneEndpoint):
|
|||
|
||||
return jsonify('Account added successfully'), HTTPStatus.OK
|
||||
|
||||
def patch(self):
|
||||
self._authenticate()
|
||||
self.request_data = json.loads(self.request.data)
|
||||
self._update_support()
|
||||
|
||||
def _validate_request(self):
|
||||
add_request = AddAccountRequest(dict(
|
||||
username=self.request_data.get('username'),
|
||||
|
@ -168,7 +186,7 @@ class AccountEndpoint(SeleneEndpoint):
|
|||
open_dataset=support_data.get('openDataset'),
|
||||
membership=support_data.get('membership'),
|
||||
payment_method=support_data.get('paymentMethod'),
|
||||
payment_account_id=support_data.get('paymentAccountId')
|
||||
payment_token=support_data.get('paymentToken')
|
||||
))
|
||||
|
||||
return support
|
||||
|
@ -188,12 +206,15 @@ class AccountEndpoint(SeleneEndpoint):
|
|||
membership_type = self.request_data['support']['membership']
|
||||
membership = None
|
||||
if membership_type != NO_MEMBERSHIP:
|
||||
payment_account = self.request_data['support']['paymentAccountId']
|
||||
payment_token = self.request_data['support']['paymentToken']
|
||||
email = self.request_data['login']['userEnteredEmail']
|
||||
plan = self._get_plan(membership_type).stripe_plan
|
||||
payment_account_id, start = self._create_stripe_subscription(payment_token, email, plan)
|
||||
membership = AccountMembership(
|
||||
type=membership_type,
|
||||
start_date=date.today(),
|
||||
payment_method=self.request_data['support']['paymentMethod'],
|
||||
payment_account_id=payment_account
|
||||
payment_account_id=payment_account_id
|
||||
)
|
||||
account = Account(
|
||||
email_address=email_address,
|
||||
|
@ -210,3 +231,59 @@ class AccountEndpoint(SeleneEndpoint):
|
|||
account,
|
||||
password=password
|
||||
)
|
||||
|
||||
def _create_stripe_subscription(self, customer_id, token, user_email, plan):
|
||||
if customer_id is None:
|
||||
customer = stripe.Customer.create(source=token, email=user_email)
|
||||
customer_id = customer.id
|
||||
subscription = stripe.Subscription.create(customer=customer_id, items=[{'plan': plan}])
|
||||
|
||||
# TODO: store subscription.id
|
||||
start = subscription.current_period_start
|
||||
start = date.fromtimestamp(start)
|
||||
return customer_id, start
|
||||
|
||||
def _get_plan(self, plan):
|
||||
with get_db_connection(self.config['DB_CONNECTION_POOL']) as db:
|
||||
return MembershipRepository(db).get_membership_by_type(plan)
|
||||
|
||||
def _update_support(self):
|
||||
with get_db_connection(self.config['DB_CONNECTION_POOL']) as db:
|
||||
membership_repository = MembershipRepository(db)
|
||||
active_membership = membership_repository.get_active_membership_by_account_id(self.account.id)
|
||||
if active_membership:
|
||||
active_membership.end_date = datetime.now()
|
||||
# TODO: use the subscription id to delete the membership on stripe
|
||||
membership_repository.finish_membership(active_membership)
|
||||
add_membership = UpdateMembership(self.request_data.get('support'))
|
||||
add_membership.validate()
|
||||
support = self.request_data['support']
|
||||
membership = support['membership']
|
||||
stripe_plan = self._get_plan(membership)
|
||||
stripe_id, start_date = self._create_stripe_subscription(
|
||||
active_membership.payment_account_id,
|
||||
None,
|
||||
self.account.email_address,
|
||||
stripe_plan
|
||||
)
|
||||
else:
|
||||
add_membership = AddMembership(self.request_data.get('support'))
|
||||
add_membership.validate()
|
||||
support = self.request_data['support']
|
||||
membership = support['membership']
|
||||
token = support['payment']
|
||||
stripe_plan = self._get_plan(membership)
|
||||
stripe_id, start_date = self._create_stripe_subscription(
|
||||
None,
|
||||
token,
|
||||
self.account.email_address,
|
||||
stripe_plan
|
||||
)
|
||||
|
||||
new_membership = AccountMembership(
|
||||
start_date=start_date,
|
||||
payment_method=STRIPE_PAYMENT,
|
||||
payment_account_id=stripe_id,
|
||||
type=membership
|
||||
)
|
||||
AccountRepository(db).add_membership(self.account.id, new_membership)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from datetime import date
|
||||
from dataclasses import dataclass
|
||||
from datetime import date
|
||||
from typing import List
|
||||
|
||||
|
||||
|
@ -19,6 +19,8 @@ class AccountMembership(object):
|
|||
payment_method: str
|
||||
payment_account_id: str
|
||||
id: str = None
|
||||
account_id: str = None
|
||||
end_date: date = None
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
|
@ -7,4 +7,5 @@ class Membership(object):
|
|||
type: str
|
||||
rate: Decimal
|
||||
rate_period: str
|
||||
stripe_plan: str
|
||||
id: str = None
|
||||
|
|
|
@ -35,7 +35,7 @@ class AccountRepository(object):
|
|||
account_id = self._add_account(account, password)
|
||||
self._add_agreements(account_id, account.agreements)
|
||||
if account.membership is not None:
|
||||
self._add_membership(account_id, account.membership)
|
||||
self.add_membership(account_id, account.membership)
|
||||
|
||||
_log.info('Added account {}'.format(account.email_address))
|
||||
|
||||
|
@ -73,7 +73,7 @@ class AccountRepository(object):
|
|||
)
|
||||
self.cursor.insert(request)
|
||||
|
||||
def _add_membership(self, acct_id: str, membership: AccountMembership):
|
||||
def add_membership(self, acct_id: str, membership: AccountMembership):
|
||||
"""A membership is optional, add it if one was selected"""
|
||||
request = DatabaseRequest(
|
||||
sql=get_sql_from_file(
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from selene.data.account import AccountMembership
|
||||
from ..entity.membership import Membership
|
||||
from ...repository_base import RepositoryBase
|
||||
|
||||
|
@ -6,6 +7,31 @@ class MembershipRepository(RepositoryBase):
|
|||
def __init__(self, db):
|
||||
super(MembershipRepository, self).__init__(db, __file__)
|
||||
|
||||
def get_membership_types(self):
|
||||
db_request = self._build_db_request(
|
||||
sql_file_name='get_membership_types.sql'
|
||||
)
|
||||
db_result = self.cursor.select_all(db_request)
|
||||
|
||||
return [Membership(**row) for row in db_result]
|
||||
|
||||
def get_membership_by_type(self, type: str):
|
||||
db_request = self._build_db_request(
|
||||
sql_file_name='get_membership_by_type.sql',
|
||||
args=dict(type=type)
|
||||
)
|
||||
db_result = self.cursor.select_one(db_request)
|
||||
return Membership(**db_result)
|
||||
|
||||
def get_active_membership_by_account_id(self, account_id) -> AccountMembership:
|
||||
db_request = self._build_db_request(
|
||||
sql_file_name='get_active_membership_by_account_id.sql',
|
||||
args=dict(account_id=account_id)
|
||||
)
|
||||
db_result = self.cursor.select_one(db_request)
|
||||
if db_result:
|
||||
return AccountMembership(**db_result)
|
||||
|
||||
def add(self, membership: Membership):
|
||||
db_request = self._build_db_request(
|
||||
'add_membership.sql',
|
||||
|
@ -21,7 +47,20 @@ class MembershipRepository(RepositoryBase):
|
|||
|
||||
def remove(self, membership: Membership):
|
||||
db_request = self._build_db_request(
|
||||
'delete_membership.sql',
|
||||
sql_file_name='delete_membership.sql',
|
||||
args=dict(membership_id=membership.id)
|
||||
)
|
||||
self.cursor.delete(db_request)
|
||||
|
||||
def finish_membership(self, membership: AccountMembership):
|
||||
db_request = self._build_db_request(
|
||||
sql_file_name='finish_membership.sql',
|
||||
args=dict(
|
||||
id=membership.id,
|
||||
membership_ts_range='[{start},{end}]'.format(
|
||||
start=membership.start_date,
|
||||
end=membership.end_date
|
||||
)
|
||||
)
|
||||
)
|
||||
self.cursor.update(db_request)
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
UPDATE
|
||||
account.account_membership
|
||||
SET
|
||||
membership_ts_range = %(membership_ts_range)s
|
||||
WHERE
|
||||
id = %(id)s
|
|
@ -0,0 +1,6 @@
|
|||
SELECT
|
||||
*
|
||||
FROM
|
||||
account.account_membership
|
||||
WHERE
|
||||
account_id = %(account_id)s and membership_ts_range @> '[now,)'
|
|
@ -0,0 +1,10 @@
|
|||
SELECT
|
||||
id,
|
||||
type,
|
||||
rate,
|
||||
rate_period,
|
||||
stripe_plan
|
||||
FROM
|
||||
account.membership
|
||||
WHERE
|
||||
type = %(type)s
|
|
@ -0,0 +1,8 @@
|
|||
SELECT
|
||||
id,
|
||||
type,
|
||||
rate,
|
||||
rate_period,
|
||||
stripe_plan
|
||||
FROM
|
||||
account.membership
|
|
@ -1,9 +0,0 @@
|
|||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@dataclass
|
||||
class AccountPreferences(object):
|
||||
id: str
|
||||
date_format: str
|
||||
time_format: str
|
||||
measurement_system: str
|
Loading…
Reference in New Issue