Skip to content

Commit

Permalink
Creates a separate subscriptions package
Browse files Browse the repository at this point in the history
  • Loading branch information
emmdim committed Oct 29, 2024
1 parent e8d7ddb commit 51b8274
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 28 deletions.
5 changes: 5 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/vocdoni/saas-backend/db"
"github.com/vocdoni/saas-backend/notifications"
"github.com/vocdoni/saas-backend/stripe"
"github.com/vocdoni/saas-backend/subscriptions"
"go.vocdoni.io/dvote/apiclient"
"go.vocdoni.io/dvote/log"
)
Expand All @@ -37,6 +38,8 @@ type APIConfig struct {
FullTransparentMode bool
// Stripe secrets
StripeClient *stripe.StripeClient
// Subscriptions permissions manager
Subscriptions *subscriptions.Subscriptions
}

// API type represents the API HTTP server with JWT authentication capabilities.
Expand All @@ -53,6 +56,7 @@ type API struct {
secret string
transparentMode bool
stripe *stripe.StripeClient
subscriptions *subscriptions.Subscriptions
}

// New creates a new API HTTP server. It does not start the server. Use Start() for that.
Expand All @@ -72,6 +76,7 @@ func New(conf *APIConfig) *API {
secret: conf.Secret,
transparentMode: conf.FullTransparentMode,
stripe: conf.StripeClient,
subscriptions: conf.Subscriptions,
}
}

Expand Down
2 changes: 1 addition & 1 deletion api/errors_definition.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ var (
ErrUserNotFound = Error{Code: 40018, HTTPstatus: http.StatusNotFound, Err: fmt.Errorf("user not found")}
ErrNoOrganizationSubscription = Error{Code: 40019, HTTPstatus: http.StatusNotFound, Err: fmt.Errorf("organization subscription not found")}
ErrOganizationSubscriptionIncative = Error{Code: 40020, HTTPstatus: http.StatusBadRequest, Err: fmt.Errorf("organization subscription not active")}
ErrNoDefaultPLan = Error{Code: 40021, HTTPstatus: http.StatusBadRequest, Err: fmt.Errorf("did not found default plan for organizaiton")}
ErrNoDefaultPLan = Error{Code: 40021, HTTPstatus: http.StatusBadRequest, Err: fmt.Errorf("did not found default plan for organization")}

ErrMarshalingServerJSONFailed = Error{Code: 50001, HTTPstatus: http.StatusInternalServerError, Err: fmt.Errorf("marshaling (server-side) JSON failed")}
ErrGenericInternalServerError = Error{Code: 50002, HTTPstatus: http.StatusInternalServerError, Err: fmt.Errorf("internal server error")}
Expand Down
2 changes: 1 addition & 1 deletion api/stripe.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (a *API) handleWebhook(w http.ResponseWriter, r *http.Request) {
MaxCensusSize: int(subscription.Items.Data[0].Quantity),
}

//TODO will only worked for new subscriptions
// TODO will only worked for new subscriptions
if err := a.db.AddSubscriptionToOrganization(org.Address, organizationSubscription); err != nil {
log.Warnf("Could not update subscription %s for organization %s: %s", subscription.ID, org.Address, err.Error())
w.WriteHeader(http.StatusBadRequest)
Expand Down
11 changes: 3 additions & 8 deletions api/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,7 @@ func (a *API) signTxHandler(w http.ResponseWriter, r *http.Request) {
}
// check if the api is not in transparent mode
if !a.transparentMode {
// get subscirption plan
plan, err := a.db.Subscription(org.Subscription.SubscriptionID)
if err != nil {
ErrNoOrganizationSubscription.Withf("could not get organization subscription: %v", err).Write(w)
return
}
// get subscription plan
switch tx.Payload.(type) {
case *models.Tx_SetAccount:
txSetAccount := tx.GetSetAccount()
Expand Down Expand Up @@ -120,7 +115,7 @@ func (a *API) signTxHandler(w http.ResponseWriter, r *http.Request) {
ErrInvalidTxFormat.With("missing fields").Write(w)
return
}
if hasPermission, err := a.db.CheckSubscriptionPermissions(tx, txNewProcess.Txtype, org, plan); !hasPermission || err != nil {
if hasPermission, err := a.subscriptions.HasPermission(tx, txNewProcess.Txtype, org); !hasPermission || err != nil {
ErrUnauthorized.Withf("user does not have permission to sign transactions: %v", err).Write(w)
return
}
Expand Down Expand Up @@ -173,7 +168,7 @@ func (a *API) signTxHandler(w http.ResponseWriter, r *http.Request) {
ErrInvalidTxFormat.With("invalid tx type").Write(w)
return
}
if hasPermission, err := a.db.CheckSubscriptionPermissions(tx, txSetProcess.Txtype, org, plan); !hasPermission || err != nil {
if hasPermission, err := a.subscriptions.HasPermission(tx, txSetProcess.Txtype, org); !hasPermission || err != nil {
ErrUnauthorized.Withf("user does not have permission to sign transactions: %v", err).Write(w)
return
}
Expand Down
5 changes: 5 additions & 0 deletions cmd/service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/vocdoni/saas-backend/notifications/smtp"
"github.com/vocdoni/saas-backend/notifications/twilio"
"github.com/vocdoni/saas-backend/stripe"
"github.com/vocdoni/saas-backend/subscriptions"
"go.vocdoni.io/dvote/apiclient"
"go.vocdoni.io/dvote/log"
)
Expand Down Expand Up @@ -146,6 +147,10 @@ func main() {
} else {
log.Fatalf("stripeApiSecret and stripeWebhookSecret are required")
}
subscriptions := subscriptions.New(&subscriptions.SubscriptionsConfig{
DB: database,
})
apiConf.Subscriptions = subscriptions
// create the local API server
api.New(apiConf).Start()
log.Infow("server started", "host", host, "port", port)
Expand Down
18 changes: 0 additions & 18 deletions db/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"go.vocdoni.io/dvote/log"
"go.vocdoni.io/proto/build/go/models"
)

// initCollections creates the collections in the MongoDB database if they
Expand Down Expand Up @@ -247,20 +246,3 @@ func readSubscriptionJSON(subscriptionsFile string) ([]*Subscription, error) {
}
return subscriptions, nil
}

func (ms *MongoStorage) CheckSubscriptionPermissions(
tx *models.Tx,
txType models.TxType,
org *Organization,
plan *Subscription,
) (bool, error) {

switch txType {
case models.TxType_NEW_PROCESS, models.TxType_SET_PROCESS_CENSUS:
newProcess := tx.GetNewProcess()
if newProcess.Process.MaxCensusSize > uint64(org.Subscription.MaxCensusSize) {
return false, fmt.Errorf("MaxCensusSize is greater than the allowed")
}
}
return true, nil
}
45 changes: 45 additions & 0 deletions subscriptions/subscriptions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package subscriptions

import (
"fmt"

"github.com/vocdoni/saas-backend/db"
"go.vocdoni.io/proto/build/go/models"
)

type SubscriptionsConfig struct {
DB *db.MongoStorage
}

type Subscriptions struct {
db *db.MongoStorage
}

func New(conf *SubscriptionsConfig) *Subscriptions {
if conf == nil {
return nil
}
return &Subscriptions{
db: conf.DB,
}
}

func (p *Subscriptions) HasPermission(
tx *models.Tx,
txType models.TxType,
org *db.Organization,
) (bool, error) {
// get subscription plan
// plan, err := p.db.Subscription(org.Subscription.SubscriptionID)
// if err != nil {
// return false, fmt.Errorf("could not get organization subscription: %v", err)
// }
switch txType {
case models.TxType_NEW_PROCESS, models.TxType_SET_PROCESS_CENSUS:
newProcess := tx.GetNewProcess()
if newProcess.Process.MaxCensusSize > uint64(org.Subscription.MaxCensusSize) {
return false, fmt.Errorf("MaxCensusSize is greater than the allowed")
}
}
return true, nil
}

0 comments on commit 51b8274

Please sign in to comment.