Centralizuota autentikacija

Posted by Saulius Grigaitis 28/04/2007 at 22h17

Sveiki. Vienas dalykas, kuris nuolat mane žavi dirbant su Ruby ir Rails, tai kalnai kokybiško ir naudingo kodo, kuriuo gana lengva pasinaudoti. Šįkart trumpai apie centralizuotą autentikacijos servisą(CAS). CAS - servisas, suteikiantis "Single Sign-On" mechanizmą. Praktiškas pavyzdys - google.com. Turite vieną paskyrą (angl. "account"), prisijungiate prie sistemos vieną kartą ir galite naudotis visais servisais, nors jie yra visiškai skirtinguose serveriuose, stovi po atskirais domenais ir išsibarstę po visą pasaulį. Trumpai apie patį paprasčiausią CAS protokolą, kuris leidžia tai įgyvendinti paprastose sistemose. Reikalingas CAS serveris ir klientas, įsimylėjusiems Ruby - rubycas-server ir rubycas-client. Be abejo, reikalinga šiek tiek pasiskaityti dokumentaciją ir sukonfigūruoti juos, tai gana paprasta, tereikia išsirinkti CAS servisą aptarnaujantį serverį, surašyti domenus ir panašiai. Dabar įdomiausia dalis - autentikacijos procesas: 1. Jungiatės prie serverio klientodomenas.lt, kuris jus automatiškai nukreipia į CAS serverį
https://serveriodomenas.lt/login?service=http://klientodomenas.lt
2. Atlikus sėkmingą autentikaciją, jus nukreipia atgal, bet jau su prikabintu bilietu
http://klientodomenas.lt/?ticket=ST-956-Lyg0BdLkgdrBO9W17bXS
3. O dabar iškeičiame bilietą į vartotojo vardą
https://serveriodomenas.lt/serviceValidate?ticket=ST-956-Lyg0BdLkgdrBO9W17bXS&service=http://klientodomenas.lt
4. Gauname vartotojo vardą:
<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
	<cas:authenticationSuccess>
		<cas:user>vartotojo_vardas</cas:user>

	</cas:authenticationSuccess>
</cas:serviceResponse>
O jungiantis iš kito CAS kliento, jūs atpažįstamas pagal sausainiuką, tad nebereikia atlikti autentifikaciją dar kartą. Be abejo, visu tuo mechanizmu rūpinasi rubycas-server ir rubycas-client, jums tereikia juos susikonfigūruoti ir naudoti.

no comments | no trackbacks

Saugumas. I dalis

Posted by Saulius Grigaitis 26/04/2007 at 22h15

Sveiki! Pradedame ciklą užrašų apie saugumą. Dauguma programuotojų, ypač nepatyrusių, lipa ant vieno ir to pačio grėblio, t.y. neapsaugo kritinių saugumo atžvilgiu objekto atributų nuo neleistino jų pakeitimo. Tarkime programuojama sistema yra gana paprasta ir naudojamas labai lengvas autorizacijos mechanizmas, tarkime klasė "Vartotojas" turi atributą "admin". Pagal šį atributą sistema ir autorizuoja vartotoją. Viskas atrodytų lyg ir gerai, vartotojo registracijos formoje nėra laukelio "admin", tad vartotojas pats negali pasikelti sau privilegijų, migracijoje "admin" laukelio reikšmė nustatytą "false" nutylint. Net ir po "Vartotojo" egzemplioriaus sukūrimo "create" "action'e", jo "admin" reikšmė nustatoma "false". Tačiau pamirštama tai padaryti "Vartotojo" egzemplioriaus atnaujinimo "action'e". Įsivaizduojame blogiausią situaciją: kažkas sužino apie atributą "admin". Tada supakuoja parametrus ir pasiunčia "POST" užklausą į "update" actioną. Pavyko! Dabar vartotojas turi administratoriaus privilegijas... Bene paprasčiausias būdas apsisaugoti nuo tokio tipo klaidų - naudoti "protected" atributus: class User < ActiveRecord::Base attr_protected :admin end

no comments | no trackbacks

Prilipęs Footer'is

Posted by Mindaugas Kurlavičius 24/04/2007 at 22h14

Kas susidūrė su CSS, žino kokia velniava yra padaryti puslapį be šlykščių ir niekaip nenusibaigiančių lentelių "table", vienodai atrodantį (ir identiškai besielgiantį) visose naršyklėse. IE košmarai, Firefox bug'ai, dar prakeiktas Safari (Opera dzin :)... Žodžiu vieno standarto nėra, kiekvienai mažai užduotėlei realizuoti nusistovėjo purvini "hakai" ir visi (naršyklių kūrėjai bei web programuotojai) toliau gyvena laimingi ir patenkinti.

Taigi šiandien papasakosiu, kaip išpręsti prilipusio footer'io problemą ištęstuotą ant IE ir Firefox.

Pačią problemą galima būtų taip apibūdinti: puslapyje yra footer'is - fiksuoto aukščio apatinis (paskutinis matomas) blokas (juosta). Kaip žinome, visi blokai (ne float) išsidėsto vienas po kito ir jeigu turinio yra daug tuose blokose, footeris nustumiamas į apačią, kuri yra "žemiau" naršyklės lango apačios ir "paskrolinus" puslapį žemyn matome prie apačios prilipusį footerį. Tačiau, ką daryti, jei puslapis neturi daug turinio, bet mes vistiek norime, kad footeris butų naršyklės lango apačioje?

Geras mano draugas vardu Google patarė štai ką:

# Layout'o šablonas
<html>
  <body>

    <div id="nonFooter">
      # Čia talpinam visą puslapio turinį
    </div>

    <div id="footer">
      # Footerio turinys
    </div>

  </body>
</html>

Ir į CSS failą įterpiam tokį kodą:

# CSS failiukas

html {
  height: 100%;
}

body {
  height: 100%;
}

#nonFooter {
  position: relative;
  min-height: 100%;
}

* html #nonFooter {
  height: 100%;
}

#footer {
  position: relative;
  /* Nurodome margin tokio paties aukščio kaip ir footeris */
  margin-top: 50px;
}

Neįprasta, keista, bet viskas veikia, užsakovas švyti, o mes pasikeikiam ir dirbam toliau...

no comments | no trackbacks

Laiko juostos

Posted by Saulius Grigaitis 24/04/2007 at 22h10

Sveiki, tęsiam globalizacijos/lokalizacijos problemą. Šiandien prireikė korektiško laiko nustatymo mechanizmo skirtingose laiko juostose esantiems vartotojams. Deja, standartinės Rails priemonės nesusitvarko su lygiadieniais, t.y. apie pusmetį kasmet turėsite neteisingą laiką :). Klientų tai visai nenudžiugintų, tad teko rasti sprendimą. Bene vienintelis patogus būdas tinkantis 1.2 versijos Rails karkasui yra tzinfo_timezone įskiepis, kuriam taip pat reikia tzinfo gem'o. Nurodom Rails'ų Active Record'ui naudoti UTC laiką, nustatydami config.active_record.default_timezone = :utc config/environment.rb faile. Pridedame vartotojų lentelėje stulpelį "time_zone". Na ir belieka pasirašyti helperius laiko konvertavimui iš UTC į vartotojo lokalų laiką ir atvirkščiai, metodo "utc_to_local" pagalba. Iki!

no comments | no trackbacks

Paveikslėlių įkrovimas

Posted by Mindaugas Kurlavičius 23/04/2007 at 22h08

Tinklapis be paveikslėlių? Na, nebent kokioje dokumentacijoje jie nereikalingi, visur kitur jau beveik nebeišsiverčiama be vaizdo ar garso klipų, ką jau kalbėti apie paveikslėlius. Logotipai, nuotraukos šiaip visumą pagyvinantys elementai... Ir svarbiausia, turi būti galimybė visą tai įkelti paprastam nepriviligijuotam vartotojui. Be to, vartotojui neturi rūpėti įkeliamo paveikslėlio dydis, t.y. tuo turi pasirūpinti tinklapio serveris.

Taigi, išties aktualus klausimas praktiškai kiekvieno tinklapio kūrėjui. Kaipgi į jį atsako "Rails"?

Deja, pats "Rails" karkasas kol kas nieko nesiūlo. Tenka kapstytis tarp trečių šalių deimančiukų (gems) ir įskiepių (plugins). Siūlomos dvi dėmesio vertos alternatyvos: "Acts as attachment" ir "File Column".

Abu įskiepiai dėl manipuliavimo paveikslėlių parametrais reikalauja "RMagick" bibliotekos, kurią man teko matyti tik "Unix" ir "Linux" platformose, bet atrodo nesunkiai galima įdiegti ir į visų taip mėgiamus "Windows".

Acts as attachment - galingas ir lankstus, sakyčiau netgi šiek tiek griozdiškas įrankis, leidžiantis įkraunamus failus saugoti DB arba failų sistemoje ir patį įkraunamą failą realizuoti kaip modelį saugomą lentelėje, kurį vėliau būtų galima perdengti kitais modeliais. Tarkime:

class File < ActiveRecord::Base
end

class Picture < File
  # Paveikslėlio matmenys, leidžiami tipai, max dydis ir t.t
end

class Xxx < File
  # ...
end

Žodžiu, per daug nesigilinant, "acts_as_attachement" API leidžia pasireikšti fantazijai, galima išspręsti sudėtingą specifinę problemą, tačiau esminis šio įskiepio trūkumas - pakankamai sudėtingas valdymo mechanizmas, be to dažniausiai tereikia tik 5% jo galimybių, o joms realizuoti nemažai laiko.

File Column - lengvesnis įrankis. Paveikslėliai (galimi ir kitokie failai) saugomi failų sistemoje, nereikia atskiro modelio ir atskiros lentelės, failus tiesiog "prikabiname" per papildomą stulpelį DB, prie jau egzistuojančio modelio. Vaizdo elementuose (rhtml) pasiekiame tuos failiukus, paruoštais pagalbiniais metodais (helpers). Taip pat "File Column" automatiškai saugo tarpinį, jau pakrautą į formą, paveiksliuką. Tad, klientui neteisingai užpildžius tam tikrus formos laukus ir "renderinus" vaizdo elementą atgal, paveikslėlis bus laikinai išsaugomas į katalogą serveryje ir tik priėmus teisingai užpildytą formą, "prikabintas" į failų sistemą ir duomenų bazę.

# Migracija
class CreateBooks < ActiveRecord::Migration
  def self.up
    create_table "books" do |t|
      #t.column :name,   :string
      #t.column :author, :string
      t.column :cover,  :string
    end
  end

  def self.down
    drop_table "books"

  end
end

# Modelis
class Books < ActiveRecord::Base
  file_column :cover, :magick => {:geometry => "100x200>"}
end

# Vaizdas
<%= image_tag url_for_file_column(@book, "cover") %>
    

no comments | no trackbacks

Unicode'as Ruby on Rails programose

Posted by Saulius Grigaitis 22/04/2007 at 22h04

Sveiki. Ramus sekmadienio vakaras. Ryt vėl įsuks į darbų verpetą, tad puikus metas apšilti ir parašyti pirmą techninį šio blogo straipsnį. Šiuo metu vystome projektą, kuriame daugiakalbystė vaidina ne paskutinį vaidmenį, tad draugausime su Unicode'u. Prireiks Ruby on Rails 1.2 ar naujesnės versijos ir keturių žingsnių:
1. Susitvarkome savo redaktorius taip, kad būtų naudojama utf-8 koduotė(dažnas šiuolaikinis redaktorius tai jau padarė pats).
2. Užtikriname, kad kiekvieno view'so antraštėje nurodyta utf-8 koduotė:
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

  ...
  </head>
3.Nurodome adapteriui, kad naudotų utf-8 koduotę faile config/database.yml:
development:
  adapter: mysql
  database: sample
  username: root
  password:
  encoding: utf8
...
Naudojant PostgreSQL, "utf8" keičiame "unicode".
4.Na ir linksmiausia dalis - nurodome duomenų bazių valdymo sistemai(DBVS), kad ji naudoti utf-8. Kiekvienai DBVS tai atliekama skirtingai, parodysiu kaip tai padaryti MySQL DBVS. Susirandame my.cnf failą, paprastai jis guli /etc direktorijoje Unix tipo sistemose. Papildome "[mysqld]" sekciją dviem įrašais:
[mysqld]
character-set-server = utf8
default-collation= utf8_unicode_ci
...
Perkrauname. Viskas. Tolesniam programų globalizavimui rekomenduoju Globalize įskiepį, bet apie jį vėliau. Iki!

no comments | no trackbacks

3, 2, 1, Startas!!!

Posted by Saulius Grigaitis 22/04/2007 at 22h03

Sveiki! Pagaliau startavom! Paklausite, kas ir ką startavo?! Trys sumanūs, veržlūs ir pamišę dėl Ruby ir Rails jaunuoliai įkūrė naują vietelę šiame didžiajame tinkle. O kam tai? Tai mums visiems – Ruby programuotojams, fanatams, entuziastams, visiems tiems, kuriems Ruby ne tik programavimo kalba, bet ir gyvenimo būdas. Čia vieta, kurioje Tu sužinosi ne tik apie Ruby ir Rails ar net kuo gyvena, kuo kvėpuoja, ką ir su kuo valgo, kaip dirba ir kaip ilsisi, apie ką svajoja,…Ruby entuziastai, o gal būt ir pats apie tai parašysi. Pasiruošk…

no comments | no trackbacks