Subscribe to RSS Feed

Databases

When the brain stops working…

You know when your brain is just not co-operating when you type ls into the mysql client console.

Continue Reading »
No Comments

Far from having a hardcore readership in Russia, I learned the hard way that running a custom WordPress installation invites hackers to manipulate its fallible security measures. It would seem that the variety of users signing-up with a .ru address have figured out how to inject php code into wordpress, and my 2.8.2 version was riddled with custom javascript, php code and lots of messages about those little blue pills that can do so much for your sex life. I have to hand-it to whoever it was, that they took the time at all to suss out the flaws and use wordpress for such a lofty goal. They even managed to get a PHP file uploaded to the application, which is both alarming and annoying.

In the end, I decided that caution was the best policy, and installed a completely fresh installation of WordPress. I’ve now disabled users (not really sure of the point of them anyway), and added HTTP authentication to my /wp-admin directory. Its now been a couple of quiet weeks, so I’m taking this to mean victory for now.

I suppose this is the main issue of using open-source software; if you find an exploit, you can cruise around the web, looking for older, vulnerable installations and attack them. The customised code of many of the websites I’ve seen are probably far more vulnerable, but their uniqueness brings a form of security of its own- its too much work for script kiddies to figure out the dynamics of every site on the web, and after all, who cares if you hack Dan Garland’s blog; better-off chasing after Disney and Microsoft, where all the geek kudos would be.
Clean-up
For anyone out there who has experienced a hacked wordpress installation and wants to clean it up, these are the steps I took:

  • Download the latest version of WordPress.
    You can find the latest verison at http://wordpress.org/latest.tar.gz.
  • Move / back-up your old installation and move it out of where apache is serving it.
    Don’t make the mistake of leaving your hacked wordpress somewhere on-line that these pricks can get at it.
  • Install your new wordpress with a new database
    You could point wordpress at your old installation, but you’re running the risk of leaving some code in a comment or post that will leave your installation vulnerable.
  • Comb through your old database to remove junk entries, spam and anything that has nasty stuff in it.
    Search particularly for long-entries, or any content not authored by yourself.
  • Use mysqldump to retrieve the bits of data you want to keep, and import them in.
    I decided to keep posts, comments, tags and categories. I used:
    mysqldump my_db -u user -p wp_links > links.sql
    mysqldump my_db -u user -p wp_posts > posts.sql
    mysqldump my_db -u user -p wp_comments > comments.sql
    mysqldump my_db -u user -p wp_links > links.sql
    mysqldump my_db -u user -p wp_term_relationships wp_terms_tp_term_taxonomy > tags.sql

    Barring the odd column here and there that may have changed between versions, this worked for me but gave me the chance to vet what content went back into the database.
    mysql my_db -u user -p < links.sql

  • Set a strong admin password
  • Set HTTP authentication on your wp-admin directory.
  • Continue Reading »
    No Comments
    Questionnaires with Ruby on Rails and AJAX

    I approached the task of undertaking market research for my new music start-up company in the typical programmer way: I made a website. I wonder how many of life’s problems I would approach in this way; but having a website seems like a good start.

    I wanted to canvass the opinion of friends and colleagues on the habits of their on-line music consumption, particularly pertaining to music subscriptions, which is a central idea within my business plan. I knew that I wasn’t an expert in marketing, so I wanted to design a form that would allow users to customise it as they went; so that they could add choices for others to select as they went along. I accomplished this using a standard ruby on rails website, a form, and some AJAX.
    Defining my data
    First of all, I wrote down a basic entity-relationship diagram on the back of an envelope of what I wanted my models to look like. I knew I was going to ask a load of questions, so I made a box to represent them. I also knew that each question would have a number of choices to select from, such as ‘Agree’ and ‘Disagree’, which is a one-to-many relationship. Next, I hoped that someone would respond to the questionnaire, by associating a subset of choices with the questions I had asked, so I made a box for ‘responses’. There were multiple choices in the questionnaire and hopefully multiple choices so I needed a many-to-many relationship.


    I even threw in a user model to store a respondant’s age and location; although it was probably overkill.
    Iteration #1 – Make some models
    I could then ask rails to do lots of work for me using the generate scripts.
    ruby script/generate model Question text:text
    ruby script/generate model Choice text:string, question_id:integer
    ruby script/generate model Response question_id:integer, choice_id:integer, user_id:integer
    ruby script/generate model User age:string, location:string
    Normally I’d start with a scaffold, but in this case I didn’t want all of the CRUD features for questions and choices available on-line. Instead, I borrowed a trick I’d learnt from hacking around on the hyperactive CMS project to ‘seed’ the database by loading in data from YML files, rather like the way fixtures work in the unit tests.

    Before I started-up webbrick, I wrote down some unit tests to ensure that the relationships were working the way I expected them to, and to ensure that the basic validation on the models were working correctly.
    class QuestionTest < ActiveSupport::TestCase

    test “required fields” do
    question = Question.new
    assert_equal false, question.save
    question.text = ‘hi’
    assert question.save
    end

    test “question has choices” do
    assert_equal false, questions(:one).choices.empty?
    assert_equal choices(:emusic), questions(:one).choices.first
    end

    end
    The first test makes sure I can’t save a question without the question’s text being populated. Rather than testing the rails validation framework, this gives me the peace of mind that I remembered to write the validation, and the test will tell me if I accidentally remove the validation in a future re-factor.

    The second test ensures that I have my model relationships configured correctly, so that I can access a question’s choices via an attribute.

    I could then go away and implement my model:
    class Question < ActiveRecord::Base

    validates_presence_of :text
    has_many :choices, :order => ‘choice_index, text’

    end
    I approached the remaining models in the same way. Before I could see anything in a browser, I needed to populate the database using the YML files I mentioned before. So I wrote the following rake task to populate the database (lives in lib/tasks).
    namespace :db do
    desc “Load seed fixtures (from db/seed) into the current environment’s database.”
    task :seed => :environment do
    require ‘active_record/fixtures’
    Dir.glob(RAILS_ROOT + ‘/db/seed/*.yml’).each do |file|
    Fixtures.create_fixtures(‘db/seed’, File.basename(file, ‘.*’))
    end
    end
    end
    Which allowed me to structure the data of my questionnaire in the following way:

    (db/seed/questions.yml)
    three:
    id: 3
    text: ‘What music websites do you currently use?’
    (db/seed/choices.yml)
    emusic:
    question_id: 3
    text: ‘E-music’

    napster:
    question_id: 3
    text: ‘Napster’

    spotify:
    question_id: 3
    text: ‘Spotify’
    I could then run rake db:seed and my database would be populated with the questionnaire data. I could now fire-up a browser and begin programming the view.
    Iteration #2: First form
    The next job was to create a form that would allow my respondents to view the questions in my database, along with the choices, and make some responses. I had a bit of plumbing to do here, without the scaffold in place, so I generated a controller, added some views and updated by routes.rb.

    Once I had a view, I could create a form. I decided to treat the form as an ordered-list, so I created a partial that would supply the HTML for each question and enclosed it in a OL and LI tag:
    <% form_tag ‘/respond’ do -%>

    <ol>
    <% @questions.each do |q| %>
    <%=render :partial => ‘questionnaires/question’, :locals => { :q => q } %>
    <% end %>
    </ol>

    <div id=”submit”>
    <p>That’s all for now! Press this button to complete the survey.</p>
    <%=submit_tag ‘Submit Questionnaire’%>
    </div>
    <% end -%>
    This approach immediately posed the problem of how to read in the form data, when the view doesn’t know what questions and choices are being visualised in advance. The solution rested in the correct naming convention that allowed rails to convert the form data into a manageable collection. I wanted a collection of responses, that would each contain a collection of those selected choices a user had made, and this is done by naming each input ‘responses, each containing a collection of choices organised by their question_id.

    So I could code my question partial (q is the current question):
    <% question_name = ‘responses’ %>
    <li class=”question” >
    <%=label_tag ‘text’ + q.id.to_s, q.text%>
    <%=text_field_tag question_name, nil, {:id=> ‘text’ + q.id.to_s} %>
    </li>
    However, I realised that I couldn’t determine what type of question is was yet; should I display a text-box, a check-box or a radio-box? Back to the drawing-board.
    Iteration #3: Multiple-choices
    I needed a way of determining what type of question I was asking: would I allow multiple responses to the same question (appropriate when asking ‘which of the following…), or only one (agree, disagree). I accomplished this by adding a allow_multiple flag to my question model, which I could then read in the view to determine whether or not to display a checkbox (for multiple responses) or a radio-box (for one-choice). When there were no choices for a question, I would assume a text-box was reuqired, and that is how the age/location fields work.

    Once I had updated my fixtures, model and database, I could return to the view:
    <% if q.choices.empty? %>
      <%=label_tag ‘text’ + q.id.to_s, q.text%>
       <%=text_field_tag question_name, nil, {:id=> ‘text’ + q.id.to_s} %>
    <% else %>
          <p><%=q.text%></p>
          <% q.choices.each do |c| %>
          <div class=”choice”>
            <%=label_tag ‘choice’ + c.id.to_s, c.text%>
            <% if q.multiple_choice %>
              <%=check_box_tag question_name, c.id, nil, :id=> ‘choice’ + c.id.to_s%>
            <% else %>
              <%=radio_button_tag question_name, c.id, nil, :id=> ‘choice’ + c.id.to_s%>
            <% end %>
          </div>
          <% end %>
    I could now view my form and see the correct input fields being displayed, ready for my controller to save the responses.
    Iteration #4: Adding new choices
    The main reason for developing a new questionnaire in rails was to allow my respondents to add choices which I hadn’t anticipated, in turn allowing others to choose the same response. This is proving useful for the ‘which music services do you use’ question, throwing-up websites I might not have otherwise heard of and I can now benchmark and investigate.

    To add a new choice, I needed a way of distinguishing which questions I would allow new choices for and which I would not, so I added another field to question called ‘allow_new’. I updated my model, fixture, database (and unit test of course!) and was ready to up-date my view.
     <% if q.allow_new %>
          <div class=”choice”>
            <label>Other (please specify)</label>
            <div id=”new<%=q.id%>”>
              <%=text_field_tag ‘newchoice’, nil, {:id => ‘newchoice’ + q.id.to_s} %>
              <%=hidden_field_tag ‘question_id’, q.id, {:id => ‘question_id’ + q.id.to_s} %>
              <%=submit_to_remote ‘add_btn’, ‘Add’, :update => (‘q’ + q.id.to_s),
              :url => ‘/addchoice’, :submit => ‘q’ + q.id.to_s%>
            </div>
          </div>
          <% end %>
    I added a textfield labelled ‘Other – please specify’ and a button with an AJAX action, so that respondants could add their new choice as they went along, without submitting the entire form. In order to achieve that, I used the submit_to_remote button, which in effect allowed me to nest multiple forms within a single form. Although intuitively, I wanted to create additonal form tags to surround the new text field, this approach didn’t seem to work cross-browser and only the one form is needed. Instead, the :submit option is used to tell javascript to serialise all of the form elements underneath the element with the given ID. The beauty is that this element doesn’t have to be a form element- so here I use the DIV surrounding the question, serialising only the text field for the new choice, along with the existing choices (which I later used to pre-populate the choices that had already been selected). I also pass along the question_id in a hidden field, so that the controller knows which question the new choice belongs to.

    IE GOTCHAS: Developers beware! This approach of including multiple AJAX submit buttons in IE is very fickle; unless you play by its rules it wont work and you’ll probably waste time trying to figure it out. Don’t fall into these traps:

  • You cannot nest multiple AJAX forms inside a larger form. It might work in Firefox, but IE won’t know which button you’ve pressed and won’t submit or update your chosen element properly. I found that I couldn’t even submit the main form using this approach!
  • You cannot nominate any element for the :submit option. I tried using the <li> element at first, but in the end I surrounded the entire <li> with a <div>, and updated that- which works fine cross-browser.
  • Iteration #5: Finishing up
    I had a working questionniare, but I wanted to ensure that at least the age and location fields were completed, and that any previously-completed form elements were not lost in the event that validation failed.

    The first task here is to ensure that the user model validates for this information:
    class User < ActiveRecord::Base

      validates_presence_of :location
      validates_numericality_of :age, :allow_nil => false

      has_many :responses

    end
    Now if I try to call save! on the User class, I’ll get an error in my controller. Using a begin/rescue block, I could now take appropriate action:
    rescue
         @errors = true
         @questions = Question.find(:all, :order => ‘question_order’)

         render :action => ‘index’
       end

      end
    I didn’t want my validation to be too sophisticated. Here I used a flag stored in @errors that I check for in my view to display an error message.

    To ensure that the form pre-populates with the previous responses, I had to pass the relevant data back out of the params object as the value parameter for the form tag helpers. In the case of the checkboxes, these values would be within a collection that stores the primary key of the choices that had been made, so a little logic was needed to detmermine whether or not to check the box controls:
    checked = prevvalue.include?(c.id.to_s) or c.text == params
    The second test here checks the new choice created by the AJAX form, determined by whether or not the text in the submitted box matches the newly-created test.

    So, an afternoon invested in a new questionnaire and hopefully some intriguing insights into our music consumption habits. If you have any observations about my approach here, or have spotted something that I could have done better or more efficiently, please leave a comment as I’d be glad to know about it.

    Of course, don’t forget to complete the questionnaire!

    http://mostrated.com/questionnaires/
    <% form_tag ‘/respond’ do -%>

    <ol>
    <% @questions.each do |q| %>

    <%=render :partial => ‘questionnaires/question’, :locals => { :q => q } %>

    <% end %>
    </ol>

    <div id=”submit”>
    <p>That’s all for now! Press this button to complete the survey.</p>
    <%=submit_tag ‘Submit Questionnaire’%>
    </div>
    <% end -%>

    Continue Reading »
    3 Comments

    When working in ruby on rails 2.0.2 I keep my development database in the default sqlite3 but use mysql for the production database on a seperate test server. I found that after a while of use from my alpha-testers, the test server database for my web app had been filling up with useful, real-life data, that I wanted to use on my development environment. So I needed a way to transfer the data from mySQL (5.0.32) into sqlite3.

    I exported the data from mySQL using the mysqldump utility. The mysqldump tool is normally used for backing up mySQL databases, but with a but of cunning can be used to export data into other formats. Firstly, since my sqlite3 development database already exists and can be recreated from the rake migration scripts, I didn’t need any of the SQL statements that modify or create the schema. You can tell mysqldump that with the –no-create-db and –no-create-info arguements to mysqldump:
    mysqldump –no-create-db –no-create-info yourdatabase
    Secondly, mysqldump uses its comma-seperated INSERT feature for brevity. However, sqlite doesn’t like this, so I wanted it to use a sepereate INSERT statement for each row. This is done with the –extended-insert=0 option
    mysqldump –no-create-db –no-create-info –extended-insert=0 yourdatabase
    Lastly, I wanted to ignore any of the comments or locking statements and output only those INSERT statements into a file. I did this using grep and piping the output:
    mysqldump –no-create-db –no-create-info –extended-insert=0 yourdatabase | grep ‘INSERT’
    you can then redirect this output into a file
    mysqldump –no-create-db –no-create-info –extended-insert=0 yourdatabase | grep ‘INSERT’ > yourdatabase.sql
    The one problem that I found with this output was that sqlite3 handles escape characters differently from mySQL, so I had to manually replace any instances of \’ with ” using my text editor.

    This yourdatabase.sql file then contains a load of INSERT statements. Since I didn’t need the data in my development database anymore, I decided that the easiest thing to do would be to just delete the db/development.sqlite3 database and use rake to rebuild the schema, to leave me a clean, empty database. This avoids problems such as clashing primary key entries.
    rm db/development.sqlite3
    rake db:create
    rake db:migrate
    Finally, to import my data into sqlite3 I used the .read command in the interactive command-line tool
    .read yourdatabase.sql

    Continue Reading »
    1 Comment