terça-feira, 8 de janeiro de 2013

Autenticação do Django utilizando old_password do mysql

No mesmo diretório do seu arquivo settings.py crie um arquivo chamado hashers.py com o seguinte conteúdo:

from django.contrib.auth.hashers import BasePasswordHasher, mask_hash

from django.utils.datastructures import SortedDict
from django.utils.crypto import constant_time_compare
from django.utils.translation import ugettext_noop as _

class MySQLOldPasswordHasher(BasePasswordHasher):
    """
    Classe para criptografar as senhas utilizando o modelo da funcao old_password do mysql 4.x
    Class to encrypt the passwords using the model of mysql 4.x  old_password function
    """
    algorithm = "mysql_old_password"

    def salt(self):
        return ''

    def encode(self, password, salt):
        nr = 1345345333
        add = 7
        nr2 = 0x12345671

        for c in (ord(x) for x in password if x not in (' ', '\t')):
            nr^= (((nr & 63)+add)*c)+ (nr << 8) & 0xFFFFFFFF
            nr2= (nr2 + ((nr2 << 8) ^ nr)) & 0xFFFFFFFF
            add= (add + c) & 0xFFFFFFFF

        password = "%08x%08x" % (nr & 0x7FFFFFFF,nr2 & 0x7FFFFFFF)
        return "%s$%s" % (self.algorithm, password)

    def verify(self, password, encoded):
        encoded_2 = self.encode(password, '')
        return constant_time_compare(encoded, encoded_2)

    def safe_summary(self, encoded):
        return SortedDict([
            (_('algorithm'), self.algorithm),
            (_('hash'), mask_hash(encoded, show=3)),
        ])

Adicone esse novo hasher no início da setting PASSWORD_HASHERS no seu arquivo settings.py:

PASSWORD_HASHERS = (
    'app.hashers.MySQLOldPasswordHasher',
    'django.contrib.auth.hashers.BCryptPasswordHasher',
    'django.contrib.auth.hashers.PBKDF2PasswordHasher',
    'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher',
    'django.contrib.auth.hashers.SHA1PasswordHasher',
    'django.contrib.auth.hashers.MD5PasswordHasher',
    'django.contrib.auth.hashers.CryptPasswordHasher',
)

A função de login fica como de costume:

from django.contrib.auth import authenticate, logout, login as authlogin
from django.core.context_processors import csrf
def logar(request):
 if request.POST:
  c = {}
  c.update(csrf(request))
  r = request.POST

  usuario = r.get('usuario')
  senha = r.get('senha')

  u = authenticate(username=usuario, password=senha)

  if u is not None:
   c = u.get_profile()
   if c:
    if c.ativo:
     if u.is_active:
      authlogin(request, u)
      # USUARIO LOGADO COM SUCESSO
      return HttpResponse('1')
    # USUARIO INATIVO     
    return HttpResponse('-3')
  # USUARIO NAO ENCONTRADO / SENHA INCORRETA
  return HttpResponse('0')
 # REQUISICAO SEM POST
 return HttpResponse('-1')


Da mesma forma pode ser feito com outros hashers. Basta adicioná-los ao arquivo hashers.py e listá-los na ordem desejada no settings como vimos acima.

Uma coisa notada analisando os algoritmos de hash disponível no Django (disponíveis em django.contrib.auth.hashers), o password gerado automático que é salvo no banco possui 3 partes separadas pelo simbolo "$":

  • Algoritmo de criptografia utilizado
  • Número de iterações
  • Hash da senha
No exemplo acima que a função old_password() do mysql não possui iterações, a segunda parte é omitda.



hasta!

quinta-feira, 20 de dezembro de 2012

Como fazer o parse de um JSON em python

Como fazer o parse de um json para alimentar conteúdo ?

Na sua view que será responsável por buscar o conteúdo faça como abaixo:

def carga(request):
 import json
 from django.conf import settings

 json_data=open("%s/arquivo.json" % settings.MEDIA_ROOT).read()
 data = json.loads(json_data)

 retorno = ""

 for i in data['raiz']:
  retorno += "<h2>%s</h2>" % (i['titulo'],)

  for v in i['itens']:
   retorno += '--> %s: %s ' % (v['titulo'], v['valor'])
  retorno += '<hr>'

 return HttpResponse(retorno)

O exemplo acima retorna o conteúdo da seguinte forma:


Titulo1

--> Item titulo1: item valor1
--> Item titulo2: item valor2
--> Item titulo3: item valor3

Titulo2

--> Item titulo1: item valor1
--> Item titulo2: item valor2
--> Item titulo3: item valor3

Titulo3

--> Item titulo1: item valor1
--> Item titulo2: item valor2



hasta!

Como utilizar RSS de um site externo como fonte de conteúdo

Deseja colocar eu seu site o conteúdo de um RSS de um site externo?
Tarefa simples para o FeedParser (http://pypi.python.org/pypi/feedparser/)

Para tal, instale o FeedParser no seu ENV:
pip install feedparser

Na sua view que será responsável por buscar o conteúdo no site externo faça como abaixo:

def sua_view(request):
    import feedparser
    d = feedparser.parse('http://www.seu_site_externo.com.br/rss/')
    noticias = d['entries']
    VARS = {
        'noticias':noticias,
    }
    return render_to_response('noticias.html', VARS, context_instance=RequestContext(request))

E para acessar os conteúdos no template, utilize os dados conforme desejado, segue a lista dos atributos que o RSS retorna:
  • comments 
  • description
  • guidislink 
  • id
  • link 
  • links 
  • published 
  • published_parsed 
  • summary 
  • summary_detail 
  • tags 
  • title 
  • title_detail

hasta!