Create a listener that will create subscriptions.
We need a listener (as discussed in c4cfceb2f2fb) that will create a
Subscription whenever an auth.Profile is created. This is the beginning of that
effort. It hasn't been tested, and all the pieces aren't in place, but it's a
rough skeleton.
We have a Dockerfile that will correctly build a minimal container for the
listener.
We have a build-docker.sh script that will correctly build a binary that will be
used in the Dockerfile.
We have a ca-certificates.crt, which are pulled from Ubuntu, and are necessary
before we can safely consume SSL endpoints.
We created a small consumer script that listens for events off NSQ, and calls
the appropriate endpoint for our Subscriptions API. This is untested, and it
doesn't build at the moment, but that's awaiting changes in the
code.secondbit.org/auth.hg package.
Finally, we have a wrapper.sh file that will expose the Stripe secret key being
used from a Kubernetes secret file as an environment variable, instead.
4 "code.secondbit.org/uuid.hg"
7 func stripeSubscriptionInMemstore(stripeSubscription string, m *Memstore) bool {
8 for _, sub := range m.subscriptions {
9 if sub.StripeSubscription == stripeSubscription {
16 func (m *Memstore) CreateSubscription(sub Subscription) error {
17 m.subscriptionLock.Lock()
18 defer m.subscriptionLock.Unlock()
20 if _, ok := m.subscriptions[sub.UserID.String()]; ok {
21 return ErrSubscriptionAlreadyExists
23 if stripeSubscriptionInMemstore(sub.StripeSubscription, m) {
24 return ErrStripeSubscriptionAlreadyExists
26 m.subscriptions[sub.UserID.String()] = sub
30 func (m *Memstore) UpdateSubscription(id uuid.ID, change SubscriptionChange) error {
32 return ErrSubscriptionChangeEmpty
35 m.subscriptionLock.Lock()
36 defer m.subscriptionLock.Unlock()
38 s, ok := m.subscriptions[id.String()]
40 return ErrSubscriptionNotFound
42 if change.StripeSubscription != nil {
43 if stripeSubscriptionInMemstore(*change.StripeSubscription, m) {
44 return ErrStripeSubscriptionAlreadyExists
48 m.subscriptions[id.String()] = s
52 func (m *Memstore) DeleteSubscription(id uuid.ID) error {
53 m.subscriptionLock.Lock()
54 defer m.subscriptionLock.Unlock()
56 _, ok := m.subscriptions[id.String()]
58 return ErrSubscriptionNotFound
60 delete(m.subscriptions, id.String())
64 func (m *Memstore) GetSubscriptions(ids []uuid.ID) (map[string]Subscription, error) {
66 return map[string]Subscription{}, ErrNoSubscriptionID
68 m.subscriptionLock.RLock()
69 defer m.subscriptionLock.RUnlock()
71 result := map[string]Subscription{}
73 for _, id := range ids {
74 s, ok := m.subscriptions[id.String()]
78 result[s.UserID.String()] = s
83 func (m *Memstore) GetSubscriptionStats() (SubscriptionStats, error) {
84 m.subscriptionLock.RLock()
85 defer m.subscriptionLock.RUnlock()
87 stats := SubscriptionStats{
88 Plans: map[string]int64{},
91 for _, subscription := range m.subscriptions {
93 stats.Plans[subscription.Plan]++
95 if subscription.Canceling {
98 if subscription.Status == "past_due" || subscription.Status == "unpaid" {