Skip to content

Commit

Permalink
Validação
Browse files Browse the repository at this point in the history
  • Loading branch information
wagnerdevocelot committed Aug 11, 2020
1 parent b1187d1 commit 9caa513
Showing 1 changed file with 47 additions and 20 deletions.
67 changes: 47 additions & 20 deletions wiki.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package main

import (
// Pacote para auxilio no tratamento e criação de erros
"errors"
"html/template"
"io/ioutil"
"log"
"net/http"

// pacote de expressões regulares
"regexp"
)

// Pagina é um struct com a estrutura que as páginas da aplicação terão
Expand All @@ -13,30 +18,37 @@ type Pagina struct {
Corpo []byte
}

// Há uma ineficiência neste código: renderizaTemplate chama ParseFiles sempre que uma página é
// renderizada. Uma abordagem melhor seria chamar ParseFiles uma vez na inicialização do programa,
// analisando todos os templates em um único *Template. Então, podemos usar o método ExecuteTemplate para
// renderizar um template específico.
// Como você deve ter observado, este programa tem uma falha de segurança séria: um usuário pode fornecer um
// caminho arbitrário para ser lido/escrito no servidor. Para atenuar isso, podemos escrever uma função para
// validar o título com uma expressão regular.

// Primeiro, criamos uma variável global chamada templates e a inicializamos com ParseFiles.
// Primeiro, adicione "regexp" à lista import. Então, podemos criar uma variável global para armazenar nossa
// expressão de validação:

// A função template.Must é um invólucro que entra em pânico quando é passado um valor error
// não nulo (nil) e, caso contrário, retorna o *Template inalterado. O panic é apropriado aqui;
// se os templates não puderem ser carregados, a única coisa sensata a fazer é sair do programa.
// A função regexp.MustCompile irá analisar e compilar a expressão regular e retornar um regexp.Regexp.
// MustCompile é diferente de Compile porque entrará em panic se a compilação da expressão falhar, enquanto
// Compile retorna um error como um segundo parâmetro.

// A função ParseFiles recebe qualquer número de argumentos de string que identificam nossos arquivos de
// template e os parseam (não sei se existe essa palavra haha) em templates que são nomeados
// após o nome base do arquivo. Se adicionássemos mais modelos ao nosso programa, adicionaríamos
// seus nomes aos argumentos da chamada ParseFiles.
var caminhovalido = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$")

// templates faz o cacheamento dos templates
var templates = template.Must(template.ParseFiles("edit.html", "view.html"))

// Em seguida, modificamos a função renderizaTemplate para chamar o método templates.ExecuteTemplate
// com o nome do template apropriado:
// Agora, vamos escrever uma função que usa a expressão caminhovalido para validar o caminho e extrair
// o título da página:

// Se o título coincide, ele será retornado junto com um valor nil de erro. Se o título for inválido,
// a função gravará um erro "404 Not Found" na conexão HTTP e retornará um erro ao handler.
// Para criar um novo erro customizado, temos que importar o pacote errors.

// Observe que o nome do template é o nome do arquivo do template, portanto, devemos anexar
// ".html" ao argumento tmpl.
func obtemTitulo(escrever http.ResponseWriter, ler *http.Request) (string, error) {
coincide := caminhovalido.FindStringSubmatch(ler.URL.Path)
if coincide == nil {
http.NotFound(escrever, ler)
return "", errors.New("Titulo da página inválido")
}
return coincide[2], nil // The title is the second subexpression.
}

// renderizaTemplate faz o parse dos arquivos tratados pelos handlers
func renderizaTemplate(escrever http.ResponseWriter, tmpl string, pagina *Pagina) {
Expand All @@ -62,9 +74,14 @@ func carregaPagina(titulo string) (*Pagina, error) {
return &Pagina{Titulo: titulo, Corpo: corpo}, nil
}

// Vamos colocar uma chamada para obtemTitulo em cada um dos handlers:

// viewHandler r o titulo e corpo da pagina em html formatado
func viewHandler(escrever http.ResponseWriter, ler *http.Request) {
titulo := ler.URL.Path[len("/view/"):]
titulo, err := obtemTitulo(escrever, ler)
if err != nil {
return
}
pagina, err := carregaPagina(titulo)
if err != nil {
http.Redirect(escrever, ler, "/edit/"+titulo, http.StatusFound)
Expand All @@ -73,23 +90,33 @@ func viewHandler(escrever http.ResponseWriter, ler *http.Request) {
renderizaTemplate(escrever, "view", pagina)
}

// Vamos colocar uma chamada para obtemTitulo em cada um dos handlers:

// editHandler carrega um formulário de edição
func editHandler(escrever http.ResponseWriter, ler *http.Request) {
titulo := ler.URL.Path[len("/edit/"):]
titulo, err := obtemTitulo(escrever, ler)
if err != nil {
return
}
pagina, err := carregaPagina(titulo)
if err != nil {
pagina = &Pagina{Titulo: titulo}
}
renderizaTemplate(escrever, "edit", pagina)
}

// Vamos colocar uma chamada para obtemTitulo em cada um dos handlers:

// A função saveHandler tratará do envio de formulários localizados nas páginas de edição
func saveHandler(escrever http.ResponseWriter, ler *http.Request) {
titulo := ler.URL.Path[len("/save/"):]
titulo, err := obtemTitulo(escrever, ler)
if err != nil {
return
}
corpo := ler.FormValue("body")
pagina := &Pagina{Titulo: titulo, Corpo: []byte(corpo)}
pagina.salvar()
err := pagina.salvar()
err = pagina.salvar()
if err != nil {
http.Error(escrever, err.Error(), http.StatusInternalServerError)
return
Expand Down

0 comments on commit 9caa513

Please sign in to comment.