diff --git a/webnote.py b/webnote.py index b217862..17857ef 100644 --- a/webnote.py +++ b/webnote.py @@ -1,13 +1,19 @@ import socket import re import json -import urlparse +from urlparse import parse_qs +import sqlite3 as lite +import httplib +import base64 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(('0.0.0.0', 8080)) s.listen(1) +userloged = None +uid = 0 +con = lite.connect('datas.db') while True: data = '' @@ -31,7 +37,7 @@ else: raise Exception('Cannot read request') - + request_headers = dict() while True: @@ -43,6 +49,7 @@ field_name = field.group(1) field_body = field.group(2) request_headers[field_name.lower()] = field_body + print request_headers data = field.group(3) else: raise Exception('Cannot read request header') @@ -51,17 +58,235 @@ response += 'HTTP/1.1 200 OK\r\n' + #linhas comentadas para previnir o uso de .notes + """ try: with open('.notes') as note_file: note_dict = json.loads(note_file.read()) except IOError: note_dict = dict() + + note_list = [] + for key in note_dict: + note_list.append(note_dict[key]) + """ + + try: + with con: + cur = con.cursor() + cur.execute("CREATE TABLE Users(Id INTEGER PRIMARY KEY, Name TEXT UNIQUE NOT NULL, Password TEXT NOT NULL)") + cur.execute("CREATE TABLE Notes(Id INTEGER PRIMARY KEY, Key TEXT UNIQUE NOT NULL, Note TEXT NOT NULL, CodeUser INTEGER NOT NULL, FOREIGN KEY(CodeUser)REFERENCES Users(id))") + except lite.OperationalError: + pass + + if resource == '/auth': + response += 'Content-Type: text/html; charset=utf-8\r\n' + response += '\r\n' + if method == 'GET': + response += """ + + + + + +
+

Insira seu usuario e senha!

+ User: +
+ Password: +
+ +
+ + + """ + elif method == 'POST': + new_dict = parse_qs(data) + username = new_dict['user'][0] + password = new_dict['password'][0] + encoded = base64.encodestring('%s:%s' % (username, password)).replace('\n', '') + username = str(username) + with con: + cur = con.cursor() + cur.execute('SELECT Password FROM Users WHERE Name=:name',{'name': username}) + row = cur.fetchall() + if row == None: + break + authent = row[0][0] + if encoded == authent: + userloged = username + cur.execute('SELECT Id from Users WHERE Name=:username',{'username':userloged}) + uid = cur.fetchone(); + #a funcao reduce realiza operacoes cumulativas em uma sequencia, da esquerda pra direita, afim de se obter um unico valor + uid = reduce(lambda rst, d: rst * 10 + d, uid) + response = '' + response += 'HTTP/1.1 418 I\'m a teapot\r\n' + response += 'Content-Type: text/html; charset=utf-8\r\n' + response += '\r\n' + response += """ + + + + + +

Sucess!

+ + + """ + else: + response = '' + response += 'HTTP/1.1 401 Unauthorized\r\n' + response += 'Content-Type: text/html; charset=utf-8\r\n' + response += '\r\n' + response += """ + + + + + +

ERROR 401 - Unauthorized

+ + + """ + + elif resource == '/register': + response += 'Content-Type: text/html; charset=utf-8\r\n' + response += '\r\n' + if method == 'GET': + response += """ + + + + + +
+

Insira seu nome e senha para registrar!

+ Name: +
+ Password: +
+ +
+ + + """ + elif method == 'POST': + new_dict = parse_qs(data) + username = new_dict['name'][0] + password = new_dict['password'][0].replace('\n','').replace(';','') + auth = base64.encodestring('%s:%s' % (username, password)).replace('\n', '') + new_note = [] + new_note.append(username) + new_note.append(auth) + try: + with con: + cur = con.cursor() + cur.execute('INSERT INTO Users(Name,Password) VALUES(?,?)', new_note) + except lite.IntegrityError: + response = '' + response += 'HTTP/1.1 409 Conflict\r\n' + response += 'Content-Type: text/html; charset=utf-8\r\n' + response += '\r\n' + response += """ + + + + + +

ERROR 409

+ + + """ + + - if resource == '/notes': - response += 'Content-Type: text/plain; charset=utf-8\r\n' + elif resource == '/notes': + if (userloged): + response += 'Content-Type: text/plain; charset=utf-8\r\n' + response += '\r\n' + #linhas comentadas para nao mostrar os valores de .notes + #for name in note_dict: + # response += '%s\n' % name + with con: + cur = con.cursor() + cur.execute('SELECT Key FROM Notes where CodeUser=:id',{'id': uid}) + while True: + rows = cur.fetchone() + if rows == None: + break + for row in rows: + response += row + response += '\r\n' + + elif resource == '/edit_note' and userloged: + response += 'Content-Type: text/html; charset=utf-8\r\n' response += '\r\n' - for name in note_dict: - response += '%s\n' % name + if method == 'GET': + with con: + cur = con.cursor() + cur.execute('SELECT * FROM Notes WHERE CodeUser =:id',{'id':uid}) + while True: + row = cur.fetchone() + if row == None: + break + row = list(row) + row = str(row) + response += row + response +='\r\n' + response += """ + + + + + +
+ Qual linha deseja mudar: +
+ Name: +
+ Content: +
+ +
+ + + """ + elif method == 'POST': + while True: + #pode haver uma concatenacao de dados e vir dados nao suportados + if request_headers['content-type'] != 'application/x-www-form-urlencoded': + response = '' + response += 'HTTP/1.1 501 Not Implemeted\r\n' + response += 'Content-Type: text/html; charset=utf-8\r\n' + response += '\r\n' + response += """ + + + + + +

ERROR 501

+ + + """ + unsuported = True + break + + if len(data) != int (request_headers['content-length']): + data += conn.recv(1024) + else: + break + + if unsuported != True: + new_dict = parse_qs(data) + key_insert = new_dict['name'][0].replace('\n','').replace(';','') + note_insert = new_dict['content'][0].replace('\n','').replace(';','') + id_where = new_dict['line'][0].replace('\n','').replace(';','') + with con: + cur = con.cursor() + #se tentar mudar uma linha que nao corresponda a este usuario, nao acontecera nada + cur.execute('UPDATE Notes SET Key=:name, Note=:content Where Id=:line AND CodeUser=:id', {'name':key_insert, 'content':note_insert, 'line':id_where, 'id':uid}) + elif resource == '/add_note': response += 'Content-Type: text/html; charset=utf-8\r\n' response += '\r\n' @@ -84,25 +309,80 @@ """ elif method == 'POST': while True: - if len(data) != int (request_headers['content-length']): - data += conn.recv(1024) - else: - break - new_dict = urlparse.parse_qs(data) - note_dict[new_dict['name'][0]] = new_dict['content'][0] - with open('.notes', 'w') as note_file: - json.dump(note_dict, note_file) + if request_headers['content-type'] != 'application/x-www-form-urlencoded': + response = '' + response += 'HTTP/1.1 501 Not Implemeted\r\n' + response += 'Content-Type: text/html; charset=utf-8\r\n' + response += '\r\n' + response += """ + + + + + +

ERROR 501

+ + + """ + unsuported = True + break + + if len(data) != int (request_headers['content-length']): + data += conn.recv(1024) + else: + break + + if unsuported != True: + new_dict = parse_qs(data) + #linhas comentadas para previnir a escrita em .notes + #note_dict[new_dict['name'][0]] = new_dict['content'][0] + #with open('.notes', 'w') as note_file: + # json.dump(note_dict, note_file) + keyins = new_dict['name'][0] + notains = new_dict['content'][0] + codeuserins = uid + new_note = [] + new_note.append(keyins) + new_note.append(notains) + new_note.append(codeuserins) + with con: + cur = con.cursor() + try: + cur.execute("INSERT INTO Notes(Key,Note,CodeUser) VALUES (?,?,?);", new_note) + except lite.IntegrityError: + response = '' + response += 'HTTP/1.1 409 Conflict\r\n' + response += 'Content-Type: text/html; charset=utf-8\r\n' + response += '\r\n' + response += """ + + + + + +

ERROR 409

+ + + """ else: response += 'Content-Type: text/plain; charset=utf-8\r\n' response += '\r\n' try: - note_match = re.match('^/notes/([a-z]+)$', resource) + note_match = re.match('^/notes/([a-z0-9]+)$', resource) if note_match is not None: - response += note_dict[note_match.group(1)] + with con: + cur = con.cursor() + if note_match.group(1).isalpha(): + cur.execute('SELECT Note from Notes WHERE Key=:name AND CodeUser=:uid' ,{'name': note_match.group(1), 'uid': uid}) + else: + cur.execute('SELECT Note from Notes WHERE Id=:id AND CodeUser=:uid' ,{'id': (int(note_match.group(1)) + 1), 'uid': uid}) + row = cur.fetchone() + response += row[0] + else: - response += 'Hello World!!!' - except KeyError: + response += 'Para uso adequado autenticar em /auth!!!' + except (KeyError, IndexError, TypeError): response = '' response += 'HTTP/1.1 404 Not Found\r\n' response += 'Content-Type: text/html; charset=utf-8\r\n' @@ -117,7 +397,6 @@ """ - conn.sendall(response) - + unsuported = False; conn.close()