jueves, 17 de diciembre de 2009

HTTPS POST

Hace poco he tenido que hacer submit HTTPS contra otra web desde una aplicación Rails, utilizando un el método POST. El código es el siguiente:


    http = Net::HTTP.new("https://www.otraweb.com", 443)
    http.use_ssl = true
    path = "/login"


    # GET request -> so the host can set his cookies
    resp, data = http.get(path, nil)
    cookie = resp.response['set-cookie']


    # POST request -> logging in
    data = "#{login=#{@username}&password=#{@password}"
    headers = {
        'Cookie' => cookie,
        'Content-Type' => 'application/x-www-form-urlencoded'
    }


    resp, data = http.post(path, data, headers)


en resp.code tendremos el código HTTP de error, y en data el HTML de la petición resultante.

martes, 25 de agosto de 2009

Limitación de tamaño en el plugin Spreadsheet

Exportando datos a excel con el plugin spreadsheet he visto que hay una limitación de tamaño, que impide generar ficheros de más de 7 megas.

Buscando y rebuscando por ahí, he encontrado un parche que lo soluciona perfectamente. Tendrás que instalar la gema ruby-ole para que funcione:

sudo gem install ruby-ole

y modificar el código del fichero workbook.rb:

require 'rubygems'
require 'ole/file_system'


def store_ole_file
# OLEWriter.open(@file){ |ole|
# ole.set_size(@biffsize)
# ole.write_header
# ole.print(@data)
# @worksheets.each{ |sheet|
# ole.print(sheet.data)
# }
# }
Ole::Storage.open @file, 'wb+' do |ole|
ole.file.open 'Book', 'w' do |f|
f.write @data
@worksheets.each { |sheet| f.write sheet.data }
end
end
end

miércoles, 5 de agosto de 2009

Autenticación contra Radius

Después de mucho buscar y mucho probar, he conseguido validar contra un servidor Radius de un cliente.

Partiendo de la libreria http://rubyforge.org/projects/ruby-radius/, y con un tcpdump esnifando paquetes UDP, al final he conseguido validar.

He tenido que modificar el fichero auth.rb de la libreria:

-- attr_reader :@packet
++ attr_reader :packet

y en packet.rb, en el metodo "each":

-- @attributes.each_pair {
-- |key, value|
-- yield(key, value)
-- }

++ sorted_attributes = @attributes.keys.sort_by{|item| ++@dict.attr_num(item)}
++ sorted_attributes.each{|item|
++ key = item
++ value = @attributes[key]
++
++ yield(key, value)
++ }

para que se envien ordenados los atributos del paquete Radius.

Ahora puedes hacer una clase como:

require 'radius/auth'

class RadiusAuthentication
def initialize(hostname, secret)
@hostname, @secret = hostname, secret
@dictionary = File.join(File.dirname(__FILE__), 'dictionary')
end

def authenticate(username, password, nasip=nil, timeout=nil)
nasip = nasip || '127.0.0.1'
timeout = timeout || 10
rad = Radius::Auth.new(@dictionary, @hostname, nasip, timeout)
return rad.check_passwd(username, password, @secret)
end
end

y en tu código de aplicación:

rad = RadiusAuthentication.new(RADIUS_SERVER, RADIUS_SECRET)
success = rad.authenticate(login, password)


Y así validas la password contra el servidor Radius. Utiliza tcpdump para ver los paquetes UDP enviados y recibidos:

tcpdump udp and port 1812 -vvv

jueves, 23 de julio de 2009

Actualizar a Rails 2.3

He tenido que actualizar algunas aplicaciones de Rails 1.1.6 a la version 2.3.

La forma más rápida y menos dolorosa, para que funcione todo, aunque no sea una aplicación REST y uses ajax_scaffold, es la siguiente:

instalar rails 2.3:
gem install rails -v=2.3.2 --source=http://gems.rubyonrails.org

renombrar application.rb por application_controller.rb
mv application.rb application_controller.rb

reemplazar el environment.rb por uno nuevo de la rails 2.3
reemplazar el boot.rb por uno nuevo de la rails 2.3

tendrás que reinstalar algunos plugins, e instalar algunos nuevos como classic_pagination para mantener la paginación original, y render_component:

ruby script/plugin install git://github.com/masterkain/classic_pagination.git
ruby script/plugin install git://github.com/lackac/render_component.git -r rails-edge



en las vistas, sustituir todos los:
<%= form_tag ... %>
...
<%= end_form_tag %>

por:
<% form_tag ... do %>
...
<% end %>

lo mismo para los <%= form_remote_tag ... %>


sustituir en vistas y controladores las variables @params y @flash por params y flash

sustituir todas las llamadas a Inflector por ActiveSupport::Inflector

actualizar a la versión nueva de prototype

si tenias mensajes de error de activerecord traducidos en config/initializers/active_record_error_messages.rb, tendrás que hacer lo siguiente:

rm config/active_record_error_messages.rb
vi config/i18n.rb

este fichero contiene:

I18n.load_path += Dir[ File.join(RAILS_ROOT, 'config', 'locales', '*.{yml}') ]
I18n.default_locale = "es" # default language

y en config/locales crear es.yml:

"es":
activerecord:
errors:
templates:
header:
one: "Error: el objeto {{model}} no se ha podido guardar"
other: "{{count}} no se permite guardar {{model}}"
body: "Ha habido problemas con los siguientes campos:"
messages:
accepted: "debe ser aceptado"
blank: "no puede estar en blanco"
confirmation: "no coincide con la confirmación"
...

miércoles, 22 de julio de 2009

SQLServer y Ruby

Después de probar la conexion ODBC contra SQLServer desde Ubuntu, nos queda conectarnos desde rails. Estoy hablando de rails 2.3.2.

Tienes que instalar las siguientes gemas (a la derecha pongo la version que he probado):

sudo gem install activerecord-sqlserver-adapter (2.2.19)
sudo gem install dbd-odbc (0.2.5)
sudo gem install dbi (0.4.2)


Tambien tienes que instalar la libreria odbc de ruby:

sudo apt-get install libdbd-odbc-ruby


Creas una conexion en database.yml:

sqlserver_development:
adapter: sqlserver
mode: odbc
dsn: MISERVIDOR
username: david
password: david


Creas un modelo en app "mi_prueba.rb" con lo siguiente:

class MiPrueba < ActiveRecord::Base
establish_connection("sqlserver_development")
end


Puedes probar en la consola con:

MiPrueba.find :first


lunes, 20 de julio de 2009

SQLServer y Ubuntu

Acabo de conectarme con SQL Server desde Ubuntu.

Hay que instalar los siguientes paquetes:

sudo apt-get install unixodbc unixodbc-dev freetds-dev sqsh tdsodbc

Editar el fichero /etc/freetds/freetds.conf y añadir las siguientes lineas:


[MISERVIDOR]
host = 192.168.1.36
port = 2301
tds version = 7.0

el valor de "tds version" varía en función de la versión de sqlserver que se esté usando. En mi caso es un SQLExpress 2005, asi que "tds version" tiene que ser 7.0. Podeis consultar las versiones aqui:

http://www.freetds.org/userguide/choosingtdsprotocol.htm

En el fichero /etc/odbc.ini:

[MISERVIDOR]
Driver = FreeTDS
Description = ODBC connection via FreeTDS
Servername = MISERVIDOR
Database = prueba_development
Trace = No
UID = david
pwd = david


He tenido problemas porque el SQL Server del que dispongo es una version SQLExpress 2005, que no admite conexiones remotas por defecto. En el panel de control de SQL Server Configuration Manager, hay que habilitar las conexiones remotas.

Si no se accede por el browser de nombres de SQLServer, tienes que definir un puerto en SQL Server Configuration Manager => Protocols for SQLExpress => TCP/IP, en "IP All" => TCP Dynamic Ports. Ahí he definido el puerto 2301, que es el que aparece en el fichero /etc/freetds/freetds.conf.

Para probar la conexion basta con ejecutar:

sqsh -S MISERVIDOR -U david -P david

Si aparece ">1" es que te has conectado. Ahora puedes ejecutar:

use prueba_development
go
select * from mitabla
go

Con la utilidad iodbcadm-gtk, tambien puedes crear el dsn. Primero tienes que definir el driver, diciendole que el fichero del driver es:
/usr/lib/odbc/libtdsodbc.so

y el fichero de setup es:
/usr/lib/libtdsS.so

Luego defines el dsn con ese driver y pruebas la conexion.