Permalink
Browse files

Update users resource.

  • Loading branch information...
1 parent a33d639 commit 09d25e3b8bda60c4251165f0e1fac4efa75d5c3e @cmeiklejohn cmeiklejohn committed Nov 14, 2012
Showing with 87 additions and 14 deletions.
  1. +1 −1 src/riak_cs_control_user_resource.erl
  2. +86 −13 src/riak_cs_control_users_resource.erl
@@ -96,7 +96,7 @@ from_json(ReqData, Context) ->
{{halt, 204}, NewReqData, NewContext}
catch
error:_ ->
- {{halt, 404}, ReqData, Context}
+ {{halt, 500}, ReqData, Context}
end;
{false, Context} ->
{{halt, 404}, ReqData, Context}
@@ -13,23 +13,63 @@
-export([init/1,
allowed_methods/2,
content_types_provided/2,
+ content_types_accepted/2,
resource_exists/2,
+ post_is_create/2,
+ create_path/2,
+ from_json/2,
to_json/2]).
-include_lib("webmachine/include/webmachine.hrl").
--record(context, {users=undefined}).
+-record(context, {users=undefined,user=undefined}).
init([]) ->
riak_cs_control_helpers:configure_s3_connection(),
- {ok, #context{users=undefined}}.
+ {ok, #context{users=undefined,user=undefined}}.
allowed_methods(ReqData, Context) ->
- {['HEAD', 'GET'], ReqData, Context}.
+ {['HEAD', 'GET', 'POST'], ReqData, Context}.
+
+post_is_create(ReqData, Context) ->
+ {true, ReqData, Context}.
+
+%% @doc Extract key out of response from riak-cs.
+extract_key_id(User) ->
+ {struct, UserDetails} = User,
+ binary_to_list(proplists:get_value(list_to_binary("key_id"), UserDetails)).
+
+%% @doc Attempt to create the user if possible, and generate the path
+%% using the key_id of the new user.
+create_path(ReqData, Context) ->
+ case maybe_create_user(ReqData, Context) of
+ {true, NewContext} ->
+ User = NewContext#context.user,
+ KeyId = extract_key_id(User),
+ Resource = "/users/" ++ KeyId,
+ NewReqData = wrq:set_resp_header("Location", Resource, ReqData),
+ {Resource, NewReqData, NewContext};
+ {false, Context} ->
+ {{halt, 500}, ReqData, Context}
+ end.
content_types_provided(ReqData, Context) ->
{[{"application/json", to_json}], ReqData, Context}.
+content_types_accepted(ReqData, Context) ->
+ {[{"application/json", from_json}], ReqData, Context}.
+
+%% @doc Handle user creation.
+from_json(ReqData, Context) ->
+ case maybe_create_user(ReqData, Context) of
+ {true, NewContext} ->
+ User = NewContext#context.user,
+ Response = mochijson2:encode({struct, [{user, User}]}),
+ {Response, ReqData, NewContext};
+ {false, Context} ->
+ {{halt, 409}, ReqData, Context}
+ end.
+
resource_exists(ReqData, Context) ->
case maybe_retrieve_users(Context) of
{true, NewContext} ->
@@ -38,20 +78,52 @@ resource_exists(ReqData, Context) ->
{false, ReqData, Context}
end.
+%% @doc Attempt to create a user, and stick into the context for
+%% serialization later. Return 409 on any error for now.
+maybe_create_user(ReqData, Context) ->
+ case Context#context.user of
+ undefined ->
+ try
+ Attributes = wrq:req_body(ReqData),
+ {_Headers, Body} = create_user(Attributes),
+ ParsedResponse = mochijson2:decode(Body),
+ {true, Context#context{user=ParsedResponse}}
+ catch
+ error:_ ->
+ {false, Context}
+ end;
+ _User ->
+ {true, Context}
+ end.
+
+%% @doc Create user.
+create_user(Attributes) ->
+ erlcloud_s3:put_object(
+ riak_cs_control_helpers:administration_bucket_name(),
+ "user",
+ Attributes,
+ [{return_response, true}],
+ [{"content-type", "application/json"}]).
+
+%% @doc Retrieve users list.
+retrieve_users() ->
+ erlcloud_s3:get_object(
+ riak_cs_control_helpers:administration_bucket_name(),
+ "users",
+ [{accept, "application/json"}]).
+
%% @doc Attempt to retrieve the user or return an exception if it doesn't
%% exist.
maybe_retrieve_users(Context) ->
case Context#context.users of
undefined ->
try
- Response = erlcloud_s3:get_object(
- riak_cs_control_helpers:administration_bucket_name(),
- "users",
- [{accept, "application/json"}]),
+ Response = retrieve_users(),
ParsedResponse = parse_multipart_response(Response),
{true, Context#context{users=ParsedResponse}}
catch
- error:_ -> {false, Context}
+ error:_ ->
+ {false, Context}
end;
_Users ->
{true, Context}
@@ -89,14 +161,15 @@ parse_multipart_response(Response) ->
%% @doc Return serialized users.
to_json(ReqData, Context) ->
- Response = case maybe_retrieve_users(Context) of
+ case maybe_retrieve_users(Context) of
{true, NewContext} ->
Users = NewContext#context.users,
- mochijson2:encode({struct, [{users, Users}]});
+ Response = mochijson2:encode({struct, [{users, Users}]}),
+ {Response, ReqData, NewContext};
{false, Context} ->
- mochijson2:encode({struct, [{users, []}]})
- end,
- {Response, ReqData, Context}.
+ Response = mochijson2:encode({struct, [{users, []}]}),
+ {Response, ReqData, Context}
+ end.
-ifdef(TEST).
-endif.

0 comments on commit 09d25e3

Please sign in to comment.