// create a wallet func (c *WalletController) Create(res http.ResponseWriter, req services.AuxRequestContext, db *services.DB) { // parse body var body walletCreateBody if err := c.ParseJsonBody(req, &body); err != nil { services.Res(res).Error(400, "invalid_body", "request body is invalid or malformed. Expects valid json body") return } // identity id is required if validator.IsNull(body.IdentityId) { services.Res(res).Error(400, "missing_parameter", "Missing required field: identity_id") return } // handle is required if validator.IsNull(body.Handle) { services.Res(res).Error(400, "missing_parameter", "Missing required field: handle") return } // password is required if validator.IsNull(body.Password) { services.Res(res).Error(400, "missing_parameter", "Missing required field: password") return } // identity id must exist identity, found, err := models.FindIdentityByObjectID(db.GetPostgresHandle(), body.IdentityId) if !found { services.Res(res).Error(404, "invalid_identity", "identity_id is unknown") return } else if err != nil { c.log.Error(err.Error()) services.Res(res).Error(500, "", "server error") return } // handle must be unique across wallets _, found, err = models.FindWalletByHandle(db.GetPostgresHandle(), body.Handle) if found { services.Res(res).Error(400, "handle_registered", "handle has been registered to another wallet") return } else if err != nil { c.log.Error(err.Error()) services.Res(res).Error(500, "", "server error") return } // password length must be 6 characters if len(body.Password) < 6 { services.Res(res).Error(400, "invalid_password", "password is too short. minimum length is 6 characters") return } // securely hash password hashedPassword, err := services.Bcrypt(body.Password, 10) if err != nil { c.log.Error("unable to hash password. reason: " + err.Error()) services.Res(res).Error(500, "", "server error") return } else { body.Password = hashedPassword } // create wallet object newWallet := models.Wallet{ ObjectID: bson.NewObjectId().Hex(), Identity: identity, Handle: body.Handle, Password: body.Password, } // create wallet err = models.CreateWallet(db.GetPostgresHandle(), &newWallet) if err != nil { c.log.Error(err.Error()) services.Res(res).Error(500, "", "server error") return } respObj, _ := services.StructToJsonToMap(newWallet) services.Res(res).Json(respObj) }
// open an object for charge/consumption. An object opened in this method // will be consumable without restriction func (c *ObjectController) Open(params martini.Params, res http.ResponseWriter, req services.AuxRequestContext, log *config.CustomLog, db *services.DB) { // TODO: get from access token // authorizing wallet id authWalletID := "55c679145fe09c74ed000001" // parse body var body objectOpenBody if err := c.ParseJsonBody(req, &body); err != nil { services.Res(res).Error(400, "invalid_body", "request body is invalid or malformed. Expects valid json body") return } // ensure open method is provided if c.validate.IsEmpty(body.OpenMethod) { services.Res(res).Error(400, "invalid_parameter", "open_method: open method is required") return } // ensure a known open method is provided if body.OpenMethod != "open" && body.OpenMethod != "open_timed" && body.OpenMethod != "open_pin" { services.Res(res).Error(400, "invalid_parameter", "unknown open type method") return } dbTx, err := db.GetPostgresHandleWithRepeatableReadTrans() if err != nil { c.log.Error(err.Error()) services.Res(res).Error(500, "", "server error") return } // get the object object, found, err := models.FindObjectByObjectID(dbTx, params["id"]) if !found { dbTx.Rollback() services.Res(res).Error(404, "not_found", "object was not found") return } else if err != nil { dbTx.Rollback() c.log.Error(err.Error()) services.Res(res).Error(500, "", "server error") return } // ensure object belongs to authorizing wallet if object.Wallet.ObjectID != authWalletID { dbTx.Rollback() services.Res(res).Error(401, "unauthorized", "objects: object does not belong to authorizing wallet") return } // set object's open property to true and open_method to `open` clearOpen(&object) object.Open = true object.OpenMethod = models.ObjectOpenDefault // for open_timed, // set 'open_time' field to indicate object open window if body.OpenMethod == "open_timed" { // ensure time field is provided if body.Time == 0 { dbTx.Rollback() services.Res(res).Error(400, "invalid_parameter", "time: open window time is required. use unix time") return } // time must be in the future now := time.Now().UTC() if !now.Before(services.UnixToTime(body.Time).UTC()) { dbTx.Rollback() services.Res(res).Error(400, "invalid_parameter", "time: use a unix time pointing to a period in the future") return } object.OpenMethod = models.ObjectOpenTimed object.OpenTime = body.Time } // for open_pin // open pin sets a pin for used by charge API if body.OpenMethod == "open_pin" { // ensure pin is provided if c.validate.IsEmpty(body.Pin) { dbTx.Rollback() services.Res(res).Error(400, "invalid_parameter", "pin: pin is required") return } // pin must be numeric if !validator.IsNumeric(body.Pin) { dbTx.Rollback() services.Res(res).Error(400, "invalid_parameter", "pin: pin must contain only numeric characters. e.g 4345") return } // pin length must be between 4 - 12 characters if len(body.Pin) < 4 || len(body.Pin) > 12 { dbTx.Rollback() services.Res(res).Error(400, "invalid_parameter", "pin: pin must have a minimum character length of 4 and maximum of 12") return } // hash pin using bcrypt pinHash, err := services.Bcrypt(body.Pin, 10) if err != nil { c.log.Error("unable to hash password. reason: " + err.Error()) services.Res(res).Error(500, "", "server error") return } object.OpenMethod = models.ObjectOpenPin object.OpenPin = pinHash } dbTx.Save(&object).Commit() services.Res(res).Json(object) }