Example #1
0
func authMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ctx := getContext(r)

		var allow bool
		if r.Method[0] == 'P' { // PUT, POST, PATCH
			allow = db.WriteAllowedAt(ctx.path, ctx.user)
		} else { // otherwise
			allow = db.ReadAllowedAt(ctx.path, ctx.user)
		}

		if !allow {
			res := responses.Unauthorized()
			w.WriteHeader(res.Code)
			json.NewEncoder(w).Encode(res)
			return
		}

		next.ServeHTTP(w, r)
	})
}
Example #2
0
func HandleGraphQL(w http.ResponseWriter, r *http.Request) {
	ctx := getContext(r)

	startPath := r.URL.Path[:len(r.URL.Path)-9]
	allow := db.ReadAllowedAt(startPath, ctx.user)
	if !allow {
		json.NewEncoder(w).Encode(GraphQLResponse{
			Errors: []GraphQLError{GraphQLError{"_read permission for this path needed."}},
		})
		return
	}

	var gql string
	switch r.Header.Get("Content-Type") {
	case "application/json":
		jsonBody := struct {
			Query string `json:"query"`
		}{}
		err := json.NewDecoder(r.Body).Decode(&jsonBody)
		if err != nil {
			json.NewEncoder(w).Encode(GraphQLResponse{
				Errors: []GraphQLError{GraphQLError{"failed to parse json: " + err.Error()}},
			})
			return
		}
		gql = jsonBody.Query
		break
	case "application/x-www-form-urlencoded":
		r.ParseForm()
		gql = r.FormValue("query")
		break
	// case "application/graphql":
	default:
		body, err := ioutil.ReadAll(r.Body)
		if err != nil {
			json.NewEncoder(w).Encode(GraphQLResponse{
				Errors: []GraphQLError{GraphQLError{"couldn't read request body."}},
			})
			return
		}
		gql = string(body)
	}

	doc, err := parser.Parse(parser.ParseParams{
		Source:  gql,
		Options: parser.ParseOptions{true, true},
	})
	if err != nil || len(doc.Definitions) != 1 {
		message := "your graphql query must describe a 'query' operation."
		if err != nil {
			message = err.Error()
		}
		json.NewEncoder(w).Encode(GraphQLResponse{
			Errors: []GraphQLError{GraphQLError{"failed to parse gql query: " + message}},
		})
		return
	}

	// we're just ignoring Args for now -- maybe we'll find an utility for them in the future
	topfields := doc.Definitions[0].(*ast.OperationDefinition).SelectionSet.Selections
	response := cmap.New()

	godeepAsyncMultiple(topfields, startPath, &response)

	w.WriteHeader(200)
	w.Header().Add("Content-Type", "application/json")
	json.NewEncoder(w).Encode(GraphQLResponse{
		Data: response.Items(),
	})
}
Example #3
0
func TestAuthUsersACL(t *testing.T) {
	g := Goblin(t)
	RegisterFailHandler(func(m string, _ ...int) { g.Fail(m) })

	g.Describe("users and permissions", func() {
		g.Before(func() {
			db.Erase()
			db.Start()
		})

		g.After(func() {
			db.End()
		})

		g.It("should start with a * permission on root", func() {
			Expect(db.GetWriteRuleAt("/")).To(Equal("*"))
			Expect(db.GetReadRuleAt("/")).To(Equal("*"))
			Expect(db.GetAdminRuleAt("")).To(Equal("*")) // "/" should equal ""
		})

		g.It("which means everybody is allowed to do anything anywhere", func() {
			Expect(db.WriteAllowedAt("/", "bob")).To(Equal(true))
			Expect(db.ReadAllowedAt("/articles", "maria")).To(Equal(true))
			Expect(db.AdminAllowedAt("/somewhere/down/on/the/path", "anyone")).To(Equal(true))
			Expect(db.WriteAllowedAt("/x/r/e/ws/sd/f/t/r/e/d/g/y", "")).To(Equal(true))
			Expect(db.ReadAllowedAt("/recipes", "anna")).To(Equal(true))
			Expect(db.AdminAllowedAt("/", "bob")).To(Equal(true))
		})

		g.It("should modify permissions arbitrarily", func() {
			Expect(db.SetRulesAt("/paper", map[string]interface{}{
				"_read":  "drawer,romancist, reader",
				"_write": "drawer, romancist",
				"_admin": "romancist",
			})).To(Succeed())
			Expect(db.SetRulesAt("/", map[string]interface{}{
				"_read":  "myself",
				"_write": "myself",
				"_admin": "myself",
			})).To(Succeed())
		})

		g.It("and allowability should reflect that", func() {
			Expect(db.WriteAllowedAt("/", "bob")).To(Equal(false))
			Expect(db.ReadAllowedAt("/articles", "maria")).To(Equal(false))
			Expect(db.AdminAllowedAt("/somewhere/down/on/the/path", "anyone")).To(Equal(false))
			Expect(db.ReadAllowedAt("/recipes", "anna")).To(Equal(false))
			Expect(db.WriteAllowedAt("/x/r/e/ws/sd/f/t/r/e/d/g/y", "")).To(Equal(false))
			Expect(db.AdminAllowedAt("/", "bob")).To(Equal(false))

			Expect(db.WriteAllowedAt("/", "myself")).To(Equal(true))
			Expect(db.WriteAllowedAt("/paper", "myself")).To(Equal(true))
			Expect(db.WriteAllowedAt("/rock", "myself")).To(Equal(true))
			Expect(db.WriteAllowedAt("/paper/planes", "myself")).To(Equal(true))
			Expect(db.WriteAllowedAt("/paper", "romancist")).To(Equal(true))
			Expect(db.WriteAllowedAt("/paper/planes", "romancist")).To(Equal(true))
			Expect(db.WriteAllowedAt("/", "romancist")).To(Equal(false))
			Expect(db.WriteAllowedAt("/paperless", "romancist")).To(Equal(false))

			Expect(db.ReadAllowedAt("/paper", "drawer")).To(Equal(true))
			Expect(db.ReadAllowedAt("/paperless", "drawer")).To(Equal(false))
			Expect(db.ReadAllowedAt("/paper/origami", "drawer")).To(Equal(true))
			Expect(db.ReadAllowedAt("/paper", "reader")).To(Equal(true))
			Expect(db.ReadAllowedAt("/paperless", "reader")).To(Equal(false))
			Expect(db.ReadAllowedAt("/paper/origami", "reader")).To(Equal(true))

			Expect(db.AdminAllowedAt("/", "myself")).To(Equal(true))
			Expect(db.AdminAllowedAt("/anywhere", "myself")).To(Equal(true))
			Expect(db.AdminAllowedAt("/paper", "myself")).To(Equal(true))
			Expect(db.AdminAllowedAt("/", "romancist")).To(Equal(false))
			Expect(db.AdminAllowedAt("/anywhere", "romancist")).To(Equal(false))
			Expect(db.AdminAllowedAt("/paper", "romancist")).To(Equal(true))
			Expect(db.AdminAllowedAt("/paper/origami", "romancist")).To(Equal(true))
			Expect(db.AdminAllowedAt("/", "reader")).To(Equal(false))
			Expect(db.AdminAllowedAt("/anywhere", "reader")).To(Equal(false))
			Expect(db.AdminAllowedAt("/paper", "reader")).To(Equal(false))
		})

		g.It("should create users", func() {
			Expect(db.SaveUser("isaiah", "12345678")).To(Succeed())
			Expect(db.SaveUser("samuel", "87654321")).To(Succeed())
			Expect(db.SaveUser("isaiah", "qwertyuu")).ToNot(Succeed())
			Expect(db.SaveUser("israel", "")).To(Succeed())
			Expect(db.SaveUser("", "asdfghjh")).ToNot(Succeed())
		})

		g.It("should validate user logins", func() {
			Expect(db.ValidUser("samuel", "87654321")).To(Equal(true))
			Expect(db.ValidUser("isaiah", "12345678")).To(Equal(true))
			Expect(db.ValidUser("isaiah", "qwertyuu")).To(Equal(false))
			Expect(db.ValidUser("israel", "")).To(Equal(true))
			Expect(db.ValidUser("", "asdfghjh")).To(Equal(false))

			Expect(db.ValidUser("", "")).To(Equal(false))
			Expect(db.ValidUser("q", "a")).To(Equal(false))
			Expect(db.ValidUser("weq", "")).To(Equal(false))
			Expect(db.ValidUser("", "ssdds")).To(Equal(false))
		})
	})
}