Пример #1
0
func (i IsNullChecker) IsFormat(data string) bool {
	return govalidator.IsNull(data)
}
Пример #2
0
// enable a service to issuer status
func (c *ServiceController) EnableIssuer(params martini.Params, res http.ResponseWriter, req services.AuxRequestContext, db *services.DB) {

	// parse request body
	var body enableIssuerBody
	if err := c.ParseJsonBody(req, &body); err != nil {
		services.Res(res).Error(400, "invalid_client", "request body is invalid or malformed. Expects valid json body")
		return
	}

	// service id is required
	if c.validate.IsEmpty(body.ServiceID) {
		services.Res(res).Error(400, "missing_parameter", "Missing required field: service_id")
		return
	}

	// ensure service exists
	service, found, err := models.FindServiceByObjectID(db.GetPostgresHandle(), body.ServiceID)
	if err != nil {
		c.log.Error(err.Error())
		services.Res(res).Error(500, "", "server error")
		return
	} else if !found {
		services.Res(res).Error(404, "not_found", "service was not found")
		return
	}

	// object name is required
	if c.validate.IsEmpty(body.ObjectName) {
		services.Res(res).Error(400, "missing_parameter", "Missing required field: object_name")
		return
	}

	// ensure no other service has used the object name
	identity, found, err := models.FindIdentityByObjectName(db.GetPostgresHandle(), body.ObjectName)
	if err != nil {
		c.log.Error(err.Error())
		services.Res(res).Error(500, "", "server error")
		return
	} else if found && identity.ObjectID != service.Identity.ObjectID {
		services.Res(res).Error(400, "invalid_object_name", "object name is not available, try a unique name")
		return
	}

	// base currency is required
	if validator.IsNull(body.BaseCurrency) {
		services.Res(res).Error(400, "missing_parameter", "Missing required field: base_currency")
		return
	}

	// base currency must be supported
	if !services.StringInStringSlice(config.SupportedBaseCurrencies, body.BaseCurrency) {
		services.Res(res).Error(400, "invalid_base_currency", "base currency is unknown")
		return
	}

	// set issuer to true
	service.Identity.Issuer = true
	service.Identity.ObjectName = strings.ToLower(body.ObjectName)
	service.Identity.BaseCurrency = body.BaseCurrency
	db.GetPostgresHandle().Save(&service)

	respObj, _ := services.StructToJsonToMap(service)
	respObj["identity"].(map[string]interface{})["soul_balance"] = service.Identity.SoulBalance
	services.Res(res).Json(respObj)
}
Пример #3
0
// create an identity
func (c *IdentityController) Create(res http.ResponseWriter, req services.AuxRequestContext, db *services.DB) {

	// parse request body
	var body identityCreateBody
	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
	}

	// full name is required
	if validator.IsNull(body.FullName) {
		services.Res(res).Error(400, "missing_parameter", "Missing required field: full_name")
		return
	}

	// email is required
	if validator.IsNull(body.Email) {
		services.Res(res).Error(400, "missing_parameter", "Missing required field: email")
		return
	}

	// email is required
	if !validator.IsEmail(body.Email) {
		services.Res(res).Error(400, "invalid_email", "email is invalid")
		return
	}

	// create identity
	newIdentity := models.Identity{
		ObjectID: bson.NewObjectId().Hex(),
		FullName: body.FullName,
		Email:    body.Email,
	}

	// if request is from Issuer controller, set issuer field to true
	if d := req.GetData("isIssuer"); d != nil && d.(bool) {

		// object is required
		if validator.IsNull(body.ObjectName) {
			services.Res(res).Error(400, "missing_parameter", "Missing required field: object_name")
			return
		}

		// base currency is required
		if validator.IsNull(body.BaseCurrency) {
			services.Res(res).Error(400, "missing_parameter", "Missing required field: base_currency")
			return
		}

		// base currency must be supported
		if !services.StringInStringSlice(config.SupportedBaseCurrencies, body.BaseCurrency) {
			services.Res(res).Error(400, "invalid_base_currency", "base currency is unknown")
			return
		}

		newIdentity.Issuer = true
		newIdentity.ObjectName = body.ObjectName
		newIdentity.BaseCurrency = body.BaseCurrency
	}

	err := models.CreateIdentity(db.GetPostgresHandle(), &newIdentity)
	if err != nil {
		c.log.Error(err.Error())
		services.Res(res).Error(500, "", "server error")
		return
	}

	// create response
	respObj, _ := services.StructToJsonToMap(newIdentity)

	if newIdentity.Issuer {
		respObj["soul_balance"] = newIdentity.SoulBalance
	}

	services.Res(res).Json(respObj)

}
Пример #4
0
// renew an issuer identity soul
func (c *IdentityController) RenewSoul(res http.ResponseWriter, req services.AuxRequestContext, db *services.DB) {

	// parse request body
	var body soulRenewBody
	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
	}

	// soul balance is required
	if body.SoulBalance == 0 {
		services.Res(res).Error(400, "missing_parameter", "Missing required field: soul_balance")
		return
	}

	// soul balance must be greater than zero
	if body.SoulBalance < MinimumObjectUnit {
		services.Res(res).Error(400, "invalid_soul_balance", "Soul balance must be equal or greater than minimum object unit which is 0.00000001")
		return
	}

	// ensure identity exists
	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
	}

	// ensure identity is an issuer
	if !identity.Issuer {
		services.Res(res).Error(400, "invalid_identity", "identity is not an issuer")
		return
	}

	// add to soul balance
	newIdentity, err := models.AddToSoulByObjectID(db.GetPostgresHandle(), identity.ObjectID, body.SoulBalance)
	if err != nil {
		c.log.Error(err.Error())
		services.Res(res).Error(500, "", "server error")
		return
	}

	// create response, hide some fields
	respObj, _ := services.StructToJsonToMap(newIdentity)

	if newIdentity.Issuer {
		respObj["soul_balance"] = newIdentity.SoulBalance
	}

	services.Res(res).Json(respObj)
}
Пример #5
0
// 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)
}
Пример #6
0
// create object controller
func (c *ObjectController) Create(res http.ResponseWriter, req services.AuxRequestContext, log *config.CustomLog, db *services.DB) {

	// parse body
	var body objectCreateBody
	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
	}

	// TODO: get client id from access token
	clientID := "kl14zFDq4SHlmmmVNHgLtE0LqCo8BTjyShOH"

	// get db transaction object
	dbTx, err := db.GetPostgresHandleWithRepeatableReadTrans()
	if err != nil {
		c.log.Error(err.Error())
		services.Res(res).Error(500, "", "server error")
		return
	}

	// get service
	service, _, _ := models.FindServiceByClientId(dbTx, clientID)

	// ensure service is an issuer
	if !service.Identity.Issuer {
		dbTx.Rollback()
		services.Res(res).Error(401, "unauthorized_service", "service is not an issuer")
		return
	}

	// type is required
	if validator.IsNull(body.Type) {
		dbTx.Rollback()
		services.Res(res).Error(400, "missing_parameter", "Missing required field: type")
		return
	}

	// ensure type is valid
	if strings.ToLower(body.Type) != models.ObjectValue && strings.ToLower(body.Type) != models.ObjectValueless {
		dbTx.Rollback()
		services.Res(res).Error(400, "invalid_type", "type can only be obj_value or obj_valueless")
		return
	}

	// wallet id is required
	if validator.IsNull(body.WalletID) {
		dbTx.Rollback()
		services.Res(res).Error(400, "missing_parameter", "Missing required field: wallet_id")
		return
	}

	// ensure number of objects is greater than 0
	if body.NumberOfObjects < 1 {
		dbTx.Rollback()
		services.Res(res).Error(400, "invalid_number_objects", "number_objects must be atleast 1 but not more than 100")
		return
	}

	// ensure number of objects is not greater than 100(the limit)
	if body.NumberOfObjects > 100 {
		dbTx.Rollback()
		services.Res(res).Error(400, "invalid_number_objects", "number_objects must not be more than 100")
		return
	}

	// for object of value, validate  unit per object
	if strings.ToLower(body.Type) == models.ObjectValue {

		if body.BalancePerObject == 0 {
			dbTx.Rollback()
			services.Res(res).Error(400, "missing_parameter", "Missing required field: unit_per_object")
			return
		}

		if body.BalancePerObject < MinimumObjectUnit {
			dbTx.Rollback()
			services.Res(res).Error(400, "invalid_unit_per_object", "unit_per_object must be equal or greater than the minimum object unit which is 0.00000001")
			return
		}

		soulBalanceRequired := float64(body.NumberOfObjects) * body.BalancePerObject
		if service.Identity.SoulBalance < soulBalanceRequired {
			dbTx.Rollback()
			services.Res(res).Error(400, "insufficient_soul_balance", fmt.Sprintf("not enough soul balance to create object(s). Requires %.2f soul balance", soulBalanceRequired))
			return
		}

		// update services soul balance
		service.Identity.SoulBalance = service.Identity.SoulBalance - soulBalanceRequired
	}

	// if meta is provided, ensure it is not greater than the limit size
	if !c.validate.IsEmpty(body.Meta) && len([]byte(body.Meta)) > MaxMetaSize {
		dbTx.Rollback()
		services.Res(res).Error(400, "invalid_meta_size", fmt.Sprintf("Meta contains too much data. Max size is %d bytes", MaxMetaSize))
		return
	}

	// ensure wallet exists
	wallet, found, err := models.FindWalletByObjectID(dbTx, body.WalletID)
	if err != nil {
		dbTx.Rollback()
		c.log.Error(err.Error())
		services.Res(res).Error(500, "", "server error")
		return
	} else if !found {
		dbTx.Rollback()
		services.Res(res).Error(404, "invalid_wallet", "wallet_id is unknown")
		return
	}

	// ensure service owns the wallet
	if service.Identity.ObjectID != wallet.Identity.ObjectID {
		dbTx.Rollback()
		services.Res(res).Error(401, "invalid_wallet", "wallet is not owned by this service. Use a wallet created by this service")
		return
	}

	// create objects
	allNewObjects := []models.Object{}
	for i := 0; i < body.NumberOfObjects; i++ {

		// generate a pin
		countryCallCode := config.CurrencyCallCodes[strings.ToUpper(service.Identity.BaseCurrency)]
		newPin, err := services.NewObjectPin(strconv.Itoa(countryCallCode))
		if err != nil {
			dbTx.Rollback()
			c.log.Error(err.Error())
			services.Res(res).Error(500, "", "server error")
			return
		}

		newObj := NewObject(newPin, body.Type, service, wallet, body.BalancePerObject, body.Meta)
		err = models.CreateObject(dbTx, &newObj)
		if err != nil {
			dbTx.Rollback()
			c.log.Error(err.Error())
			services.Res(res).Error(500, "", "server error")
			return
		}
		allNewObjects = append(allNewObjects, newObj)
	}

	// update identity's soul balance
	dbTx.Save(service.Identity).Commit()
	services.Res(res).Json(allNewObjects)
}