Maintain data integrity by server-side validation of input data
defmodule UserController do
use MyApp.Web, :controller
def show(conn, params) do
user = Repo.get(User, params["id"])
render(conn, "show.json", user: user)
end
def update(conn, params) do
user = Repo.get(User, params["id"])
user_changes = Map.from_struct(params["user"])
changeset = User.changeset(user, user_changes)
case Repo.update(changeset) do
{:ok, user} ->
render(conn, "show.json", user: user)
{:error, changeset} ->
conn
|> put_status(:unprocessable_entity)
|> render(MyApp.ChangesetView, "error.json", changeset: changeset)
end
end
end
This code fetches a user record and sends it in the response, then takes user data from a subsequent request and updates the user record without any validation. If the received data is invalid, it could lead to data integrity issues.
defmodule UserController do
use MyApp.Web, :controller
def show(conn, params) do
user = Repo.get(User, params["id"])
render(conn, "show.json", user: user)
end
def update(conn, params) do
user = Repo.get(User, params["id"])
user_changes = Map.from_struct(params["user"])
if valid_user_data?(user_changes) do
changeset = User.changeset(user, user_changes)
case Repo.update(changeset) do
{:ok, user} ->
render(conn, "show.json", user: user)
{:error, changeset} ->
conn
|> put_status(:unprocessable_entity)
|> render(MyApp.ChangesetView, "error.json", changeset: changeset)
end
else
send_resp(conn, 400, "Invalid user data")
end
end
defp valid_user_data?(data) do
# Implement validation logic here
end
end
In the secure code example, the incoming user data is validated before it is used to update the user record. If the data is not valid, an error response is returned. This prevents an attacker from submitting invalid data.