From d2877982a261bc621b57031ad78f4ed10230be3c Mon Sep 17 00:00:00 2001 From: Steve Coast Date: Sat, 29 Jul 2006 10:09:52 +0000 Subject: [PATCH] more skelaton stuff --- app/controllers/application.rb | 47 ++++++- app/controllers/node_controller.rb | 189 +++++++++++++++++++++++++++++ app/helpers/node_helper.rb | 2 + app/models/node.rb | 4 + app/models/user.rb | 16 +++ db/migrate/004_create_nodes.rb | 11 ++ 6 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 app/controllers/node_controller.rb create mode 100644 app/helpers/node_helper.rb create mode 100644 app/models/node.rb create mode 100644 db/migrate/004_create_nodes.rb diff --git a/app/controllers/application.rb b/app/controllers/application.rb index 537de40d7..6cd6dac06 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -1,4 +1,49 @@ # Filters added to this controller will be run for all controllers in the application. # Likewise, all the methods added will be available for all controllers. class ApplicationController < ActionController::Base -end \ No newline at end of file + + + + # HTTP AUTH stuff for the API + + def authorize(realm='Web Password', errormessage="Could't authenticate you") + username, passwd = get_auth_data + # check if authorized + # try to get user + if user = User.authenticate(username, passwd) + # user exists and password is correct ... horray! + if user.methods.include? 'lastlogin' + # note last login + @session['lastlogin'] = user.lastlogin + user.last.login = Time.now + user.save() + @session["User.id"] = user.id + end + else + # the user does not exist or the password was wrong + @response.headers["Status"] = "Unauthorized" + @response.headers["WWW-Authenticate"] = "Basic realm=\"#{realm}\"" + render_text(errormessage, 401) + end + end + + private + def get_auth_data + user, pass = '', '' + # extract authorisation credentials + if request.env.has_key? 'X-HTTP_AUTHORIZATION' + # try to get it where mod_rewrite might have put it + authdata = @request.env['X-HTTP_AUTHORIZATION'].to_s.split + elsif request.env.has_key? 'HTTP_AUTHORIZATION' + # this is the regular location + authdata = @request.env['HTTP_AUTHORIZATION'].to_s.split + end + + # at the moment we only support basic authentication + if authdata and authdata[0] == 'Basic' + user, pass = Base64.decode64(authdata[1]).split(':')[0..1] + end + return [user, pass] + end + +end diff --git a/app/controllers/node_controller.rb b/app/controllers/node_controller.rb new file mode 100644 index 000000000..cafc0f00f --- /dev/null +++ b/app/controllers/node_controller.rb @@ -0,0 +1,189 @@ +class NodeController < ApplicationController + require 'xml/libxml' + + before_filter :authorize + + def create + if request.post? + userid = dao.useridfromcreds(r.user, r.get_basic_auth_pw) + doc = Document.new $stdin.read + + doc.elements.each('osm/node') do |pt| + lat = pt.attributes['lat'].to_f + lon = pt.attributes['lon'].to_f + xmlnodeid = pt.attributes['id'].to_i + + tags = [] + pt.elements.each('tag') do |tag| + tags << [tag.attributes['k'],tag.attributes['v']] + end + + tags = tags.collect { |k,v| "#{k}=#{v}" }.join(';') + + tags = '' unless tags + if xmlnodeid == nodeid && userid != 0 + if nodeid == 0 + new_node_id = dao.create_node(lat, lon, userid, tags) + if new_node_id + puts new_node_id + exit + else + exit HTTP_INTERNAL_SERVER_ERROR + end + else + node = dao.getnode(nodeid) + if node + #FIXME: need to check the node hasn't moved too much + if dao.update_node?(nodeid, userid, lat, lon, tags) + exit + else + exit HTTP_INTERNAL_SERVER_ERROR + end + else + exit HTTP_NOT_FOUND + end + end + + else + exit BAD_REQUEST + end + end + exit HTTP_INTERNAL_SERVER_ERROR + + + end + end + + + def rest + + # + # POST ??? + # + + if request.post? + nodeid = r.args.match(/nodeid=([0-9]+)/).captures.first.to_i + userid = dao.useridfromcreds(r.user, r.get_basic_auth_pw) + doc = Document.new $stdin.read + + doc.elements.each('osm/node') do |pt| + lat = pt.attributes['lat'].to_f + lon = pt.attributes['lon'].to_f + xmlnodeid = pt.attributes['id'].to_i + + tags = [] + pt.elements.each('tag') do |tag| + tags << [tag.attributes['k'],tag.attributes['v']] + end + + tags = tags.collect { |k,v| "#{k}=#{v}" }.join(';') + + tags = '' unless tags + if xmlnodeid == nodeid && userid != 0 + if nodeid == 0 + new_node_id = dao.create_node(lat, lon, userid, tags) + if new_node_id + puts new_node_id + exit + else + exit HTTP_INTERNAL_SERVER_ERROR + end + else + node = dao.getnode(nodeid) + if node + #FIXME: need to check the node hasn't moved too much + if dao.update_node?(nodeid, userid, lat, lon, tags) + exit + else + exit HTTP_INTERNAL_SERVER_ERROR + end + else + exit HTTP_NOT_FOUND + end + end + + else + exit BAD_REQUEST + end + end + exit HTTP_INTERNAL_SERVER_ERROR + + end + + # + # GET ??? + # + + if request.get? + node = node.find(params[:id]) + doc = Document.new + doc.encoding = "UTF-8" + root = Node.new 'osm' + root['version'] = '0.4' + root['generator'] = 'OpenStreetMap server' + doc.root = root + el1 = Node.new 'node' + el1['id'] = node.id.to_s + el1['lat'] = node.latitude.to_s + el1['lon'] = node.longitude.to_s + split_tags(el1, node.tags) + el1['visible'] = node.visible.to_s + el1['timestamp'] = node.timestamp + root << el1 + + render :text => doc.to_s, :template => false + end + + # + # DELETE???? + # + + if request.delete? + userid = dao.useridfromcreds(r.user, r.get_basic_auth_pw) + #cgi doesnt work with DELETE so extract manually: + nodeid = r.args.match(/nodeid=([0-9]+)/).captures.first.to_i + + if userid > 0 && nodeid != 0 + node = dao.getnode(nodeid) + if node + if node.visible + if dao.delete_node?(nodeid, userid) + exit + else + exit HTTP_INTERNAL_SERVER_ERROR + end + else + exit HTTP_GONE + end + else + exit HTTP_NOT_FOUND + end + else + exit BAD_REQUEST + + end + + + end + + + end + + private + def split_tags(el, tags) + tags.split(';').each do |tag| + parts = tag.split('=') + key = '' + val = '' + key = parts[0].strip unless parts[0].nil? + val = parts[1].strip unless parts[1].nil? + if key != '' && val != '' + el2 = Node.new('tag') + el2['k'] = key.to_s + el2['v'] = val.to_s + el << el2 + end + end + end + +end diff --git a/app/helpers/node_helper.rb b/app/helpers/node_helper.rb new file mode 100644 index 000000000..ff049b0fc --- /dev/null +++ b/app/helpers/node_helper.rb @@ -0,0 +1,2 @@ +module NodeHelper +end diff --git a/app/models/node.rb b/app/models/node.rb new file mode 100644 index 000000000..914e90b7e --- /dev/null +++ b/app/models/node.rb @@ -0,0 +1,4 @@ +class Node < ActiveRecord::Base + set_table_name 'current_nodes' + belongs_to :user +end diff --git a/app/models/user.rb b/app/models/user.rb index cfcbfd351..6bedfbeb3 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,3 +1,19 @@ +require 'digest/md5' + class User < ActiveRecord::Base has_many :traces + + def passwd=(str) + write_attribute("pass_crypt", Digest::MD5.hexdigest(str)) + end + + def passwd + return self.pass_crypt + end + + def self.authenticate(username, passwd) + find_first([ "display_name = ? AND pass_crypt =?", + username, + Digest::MD5.hexdigest(passwd) ]) + end end diff --git a/db/migrate/004_create_nodes.rb b/db/migrate/004_create_nodes.rb new file mode 100644 index 000000000..8031a0aee --- /dev/null +++ b/db/migrate/004_create_nodes.rb @@ -0,0 +1,11 @@ +class CreateNodes < ActiveRecord::Migration + def self.up + create_table :nodes do |t| + # t.column :name, :string + end + end + + def self.down + drop_table :nodes + end +end -- 2.43.2