// AccountMatchesParam returns an AuthCheck that grants access if paramName is the same // as the account's ID; so, for instance, on a route to /accounts/:accountId, with // a request to /accounts/asdf, the AuthCheck will return true if the account's ID is asdf. // As a special case, account.Nobody and account.Super will never match in this method. func AccountMatchesParam(paramName string) AuthCheck { return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error { var acct account.Account if err := GetAccount(ctx, &acct); err != nil { return err } else if acct.Super() || acct.Nobody() { return ErrAccountIDDoesNotMatch } else if acct.Key(ctx).Encode() != kami.Param(ctx, paramName) { return ErrAccountIDDoesNotMatch } else { return nil } } }
func deleteNote(ctx context.Context, req interface{}) (interface{}, *ErrorResponse) { db := ctx.Value("db").(*gorp.DbMap) noteId, err := strconv.Atoi(kami.Param(ctx, "noteId")) if err != nil { return nil, &ErrorResponse{ http.StatusBadRequest, fmt.Sprintf("Invalid note id format: %v", err), } } note := new(model.Note) err = db.SelectOne(note, "select * from notes where id = ?", noteId) if err != nil { return nil, &ErrorResponse{ http.StatusBadRequest, fmt.Sprintf("Query failed: %v", err), } } if _, err := db.Delete(note); err != nil { return nil, &ErrorResponse{ http.StatusInternalServerError, fmt.Sprintf("Delete failed: %v", err), } } return nil, nil }
func updateNote(ctx context.Context, req interface{}) (interface{}, *ErrorResponse) { db := ctx.Value("db").(*gorp.DbMap) newNote := req.(*model.Note) noteId, err := strconv.Atoi(kami.Param(ctx, "noteId")) if err != nil { return nil, &ErrorResponse{ http.StatusBadRequest, fmt.Sprintf("Invalid note id format: %v", err), } } note := new(model.Note) err = db.SelectOne(note, "select * from notes where id = ?", noteId) if err != nil { return nil, &ErrorResponse{ http.StatusBadRequest, fmt.Sprintf("Query failed: %v", err), } } note.Title = newNote.Title note.Content = newNote.Content note.OwnerId = newNote.OwnerId note.UpdatedAt = time.Now().UnixNano() if _, err := db.Update(note); err != nil { return nil, &ErrorResponse{ http.StatusInternalServerError, fmt.Sprintf("Update failed: %v", err), } } return note, nil }
func confirmRegistration(ctx context.Context, w http.ResponseWriter, r *http.Request) { u := User{} token := kami.Param(ctx, "token") if !bson.IsObjectIdHex(token) { http.Error(w, "Confirmation token is invalid", http.StatusInternalServerError) return } change := mgo.Change{ Update: bson.M{"$set": bson.M{"confirmed": true}}, ReturnNew: true, } users := userStorage(ctx) info, err := users.FindId(bson.ObjectIdHex(token)).Apply(change, &u) if err != nil { http.Error(w, "Confirmation token is invalid", http.StatusInternalServerError) return } if info.Updated == 1 { fmt.Printf("User %s was confirmed\n", u.Email) } http.Redirect(w, r, "/users", http.StatusFound) }
func viewUser(ctx context.Context, w http.ResponseWriter, r *http.Request) { email := kami.Param(ctx, "email") u, err := getUser(ctx, email) if err != nil { renderTemplate(w, "message", fmt.Sprintf("No user with email '%s' exists", email)) } else { renderTemplate(w, "view", u) } }
func checkPermissions(ctx context.Context, w http.ResponseWriter) string { username := ctx.Value("auth").(string) email := kami.Param(ctx, "email") if username != email { http.Error(w, "You can edit only your profile!", http.StatusForbidden) return "" } return email }
func searchHandler(ctx context.Context, w http.ResponseWriter, r *http.Request) { keyword := kami.Param(ctx, "keyword") result, err := search.Search(keyword) if err != nil { fmt.Println(err) return } json, _ := json.Marshal(result) fmt.Fprintf(w, string(json)) }
func BenchmarkParameter(b *testing.B) { kami.Reset() kami.Get("/hello/:name", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { kami.Param(ctx, "name") }) req, _ := http.NewRequest("GET", "/hello/bob", nil) b.ResetTimer() for n := 0; n < b.N; n++ { resp := httptest.NewRecorder() kami.Handler().ServeHTTP(resp, req) } }
func BenchmarkParameter5(b *testing.B) { kami.Reset() kami.Get("/:a/:b/:c/:d/:e", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { for _, v := range []string{"a", "b", "c", "d", "e"} { kami.Param(ctx, v) } }) req, _ := http.NewRequest("GET", "/a/b/c/d/e", nil) b.ResetTimer() for n := 0; n < b.N; n++ { resp := httptest.NewRecorder() kami.Handler().ServeHTTP(resp, req) } }
func TestKami(t *testing.T) { kami.Reset() kami.Use("/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { return context.WithValue(ctx, "test1", "1") }) kami.Use("/v2/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { return context.WithValue(ctx, "test2", "2") }) kami.Get("/v2/papers/:page", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { page := kami.Param(ctx, "page") if page == "" { panic("blank page") } io.WriteString(w, page) test1 := ctx.Value("test1").(string) test2 := ctx.Value("test2").(string) if test1 != "1" || test2 != "2" { t.Error("unexpected ctx value:", test1, test2) } }) resp := httptest.NewRecorder() req, err := http.NewRequest("GET", "/v2/papers/3", nil) if err != nil { t.Fatal(err) } kami.Handler().ServeHTTP(resp, req) if resp.Code != http.StatusOK { t.Error("should return HTTP OK", resp.Code, "≠", http.StatusOK) } data, err := ioutil.ReadAll(resp.Body) if err != nil { panic(err) } if string(data) != "3" { t.Error("expected page 3, got", string(data)) } }
func work(ctx context.Context, w http.ResponseWriter, r *http.Request) { name := kami.Param(ctx, "name") fmt.Println("**********request has come**************") fmt.Println(name) }
func hello(ctx context.Context, w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Hello, %s!", kami.Param(ctx, "name")) }
func greet(ctx context.Context, w http.ResponseWriter, r *http.Request) { hello := greeting.FromContext(ctx) name := kami.Param(ctx, "name") fmt.Fprintf(w, "%s, %s!", hello, name) }
func greet(ctx context.Context, w http.ResponseWriter, r *http.Request) { name := kami.Param(ctx, "name") fmt.Fprintf(w, "%s, %s!", "hello", name) }
// TODO: this mostly a copy/paste of kami_test.go, rewrite it! func TestKamiMux(t *testing.T) { mux := kami.New() // normal stuff mux.Use("/mux/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { return context.WithValue(ctx, "test1", "1") }) mux.Use("/mux/v2/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { return context.WithValue(ctx, "test2", "2") }) mux.Get("/mux/v2/papers/:page", func(ctx context.Context, w http.ResponseWriter, r *http.Request) { page := kami.Param(ctx, "page") if page == "" { panic("blank page") } io.WriteString(w, page) test1 := ctx.Value("test1").(string) test2 := ctx.Value("test2").(string) if test1 != "1" || test2 != "2" { t.Error("unexpected ctx value:", test1, test2) } }) // 404 stuff mux.Use("/mux/missing/", func(ctx context.Context, w http.ResponseWriter, r *http.Request) context.Context { return context.WithValue(ctx, "ok", true) }) mux.NotFound(func(ctx context.Context, w http.ResponseWriter, r *http.Request) { ok, _ := ctx.Value("ok").(bool) if !ok { w.WriteHeader(http.StatusInternalServerError) return } w.WriteHeader(http.StatusTeapot) }) stdMux := http.NewServeMux() stdMux.Handle("/mux/", mux) // test normal stuff resp := httptest.NewRecorder() req, err := http.NewRequest("GET", "/mux/v2/papers/3", nil) if err != nil { t.Fatal(err) } stdMux.ServeHTTP(resp, req) if resp.Code != http.StatusOK { t.Error("should return HTTP OK", resp.Code, "≠", http.StatusOK) } data, err := ioutil.ReadAll(resp.Body) if err != nil { panic(err) } if string(data) != "3" { t.Error("expected page 3, got", string(data)) } // test 404 resp = httptest.NewRecorder() req, err = http.NewRequest("GET", "/mux/missing/hello", nil) if err != nil { t.Fatal(err) } stdMux.ServeHTTP(resp, req) if resp.Code != http.StatusTeapot { t.Error("should return HTTP Teapot", resp.Code, "≠", http.StatusTeapot) } }