Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

convert the passwd storing interface to be more RESTful

  • Loading branch information...
commit 6201e57fb6d9eb6fba236368022427322305bc86 1 parent 20532de
Anil Madhavapeddy authored
View
10 client/ocaml/lifedb.ml
@@ -64,6 +64,16 @@ module Rpc = struct
rows: tr list
>
and decls = decl list
+ and passwd_t = <
+ password: string;
+ comment: string
+ >
+ and passwd_r = <
+ service: string;
+ username: string;
+ password: string;
+ comment: string
+ >
end
module Task = struct
View
39 keychain_schema.ml
@@ -112,18 +112,20 @@ module Passwd = struct
set_username : string -> unit;
encpasswd : string;
set_encpasswd : string -> unit;
+ comment : string;
+ set_comment : string -> unit;
save: int64; delete: unit
>
let init db =
- let sql = "create table if not exists passwd (id integer primary key autoincrement,service text,ctime real,username text,encpasswd text);" in
+ let sql = "create table if not exists passwd (id integer primary key autoincrement,service text,ctime real,username text,encpasswd text,comment text);" in
db_must_ok db (fun () -> Sqlite3.exec db.db sql);
let sql = "CREATE UNIQUE INDEX IF NOT EXISTS passwd_grp_service__username_idx ON passwd (service,username) " in
db_must_ok db (fun () -> Sqlite3.exec db.db sql);
()
(* object definition *)
- let t ?(id=None) ~service ~ctime ~username ~encpasswd db : t = object
+ let t ?(id=None) ~service ~ctime ~username ~encpasswd ~comment db : t = object
(* get functions *)
val mutable _id = id
method id : int64 option = _id
@@ -135,6 +137,8 @@ module Passwd = struct
method username : string = _username
val mutable _encpasswd = encpasswd
method encpasswd : string = _encpasswd
+ val mutable _comment = comment
+ method comment : string = _comment
(* set functions *)
method set_id v =
@@ -147,6 +151,8 @@ module Passwd = struct
_username <- v
method set_encpasswd v =
_encpasswd <- v
+ method set_comment v =
+ _comment <- v
(* admin functions *)
method delete =
@@ -163,24 +169,26 @@ module Passwd = struct
(* insert any foreign-one fields into their table and get id *)
let _curobj_id = match _id with
|None -> (* insert new record *)
- let sql = "INSERT INTO passwd VALUES(NULL,?,?,?,?)" in
+ let sql = "INSERT INTO passwd VALUES(NULL,?,?,?,?,?)" in
let stmt = Sqlite3.prepare db.db sql in
db_must_ok db (fun () -> Sqlite3.bind stmt 1 (let v = _service in Sqlite3.Data.TEXT v));
db_must_ok db (fun () -> Sqlite3.bind stmt 2 (let v = _ctime in Sqlite3.Data.FLOAT v));
db_must_ok db (fun () -> Sqlite3.bind stmt 3 (let v = _username in Sqlite3.Data.TEXT v));
db_must_ok db (fun () -> Sqlite3.bind stmt 4 (let v = _encpasswd in Sqlite3.Data.TEXT v));
+ db_must_ok db (fun () -> Sqlite3.bind stmt 5 (let v = _comment in Sqlite3.Data.TEXT v));
db_must_done db (fun () -> Sqlite3.step stmt);
let __id = Sqlite3.last_insert_rowid db.db in
_id <- Some __id;
__id
|Some id -> (* update *)
- let sql = "UPDATE passwd SET service=?,ctime=?,username=?,encpasswd=? WHERE id=?" in
+ let sql = "UPDATE passwd SET service=?,ctime=?,username=?,encpasswd=?,comment=? WHERE id=?" in
let stmt = Sqlite3.prepare db.db sql in
db_must_ok db (fun () -> Sqlite3.bind stmt 1 (let v = _service in Sqlite3.Data.TEXT v));
db_must_ok db (fun () -> Sqlite3.bind stmt 2 (let v = _ctime in Sqlite3.Data.FLOAT v));
db_must_ok db (fun () -> Sqlite3.bind stmt 3 (let v = _username in Sqlite3.Data.TEXT v));
db_must_ok db (fun () -> Sqlite3.bind stmt 4 (let v = _encpasswd in Sqlite3.Data.TEXT v));
- db_must_ok db (fun () -> Sqlite3.bind stmt 5 (Sqlite3.Data.INT id));
+ db_must_ok db (fun () -> Sqlite3.bind stmt 5 (let v = _comment in Sqlite3.Data.TEXT v));
+ db_must_ok db (fun () -> Sqlite3.bind stmt 6 (Sqlite3.Data.INT id));
db_must_done db (fun () -> Sqlite3.step stmt);
id
in
@@ -189,7 +197,7 @@ module Passwd = struct
end
(* General get function for any of the columns *)
- let get ?(id=None) ?(service=None) ?(ctime=None) ?(username=None) ?(encpasswd=None) ?(custom_where=("",[])) db =
+ let get ?(id=None) ?(service=None) ?(ctime=None) ?(username=None) ?(encpasswd=None) ?(comment=None) ?(custom_where=("",[])) db =
(* assemble the SQL query string *)
let q = "" in
let _first = ref true in
@@ -199,8 +207,9 @@ module Passwd = struct
let q = match ctime with |None -> q |Some b -> q ^ (f()) ^ "passwd.ctime=?" in
let q = match username with |None -> q |Some b -> q ^ (f()) ^ "passwd.username=?" in
let q = match encpasswd with |None -> q |Some b -> q ^ (f()) ^ "passwd.encpasswd=?" in
+ let q = match comment with |None -> q |Some b -> q ^ (f()) ^ "passwd.comment=?" in
let q = match custom_where with |"",_ -> q |w,_ -> q ^ (f()) ^ "(" ^ w ^ ")" in
- let sql="SELECT passwd.id, passwd.service, passwd.ctime, passwd.username, passwd.encpasswd FROM passwd " ^ q in
+ let sql="SELECT passwd.id, passwd.service, passwd.ctime, passwd.username, passwd.encpasswd, passwd.comment FROM passwd " ^ q in
let stmt=Sqlite3.prepare db.db sql in
(* bind the position variables to the statement *)
let bindpos = ref 1 in
@@ -224,6 +233,10 @@ module Passwd = struct
db_must_ok db (fun () -> Sqlite3.bind stmt !bindpos (Sqlite3.Data.TEXT v));
incr bindpos
);
+ ignore(match comment with |None -> () |Some v ->
+ db_must_ok db (fun () -> Sqlite3.bind stmt !bindpos (Sqlite3.Data.TEXT v));
+ incr bindpos
+ );
ignore(match custom_where with |_,[] -> () |_,eb ->
List.iter (fun b ->
db_must_ok db (fun () -> Sqlite3.bind stmt !bindpos b);
@@ -258,6 +271,11 @@ module Passwd = struct
|Sqlite3.Data.NULL -> failwith "null of_stmt"
|x -> Sqlite3.Data.to_string x)
)
+ ~comment:(
+ (match Sqlite3.column stmt 5 with
+ |Sqlite3.Data.NULL -> failwith "null of_stmt"
+ |x -> Sqlite3.Data.to_string x)
+ )
(* foreign fields *)
db
in
@@ -267,7 +285,7 @@ module Passwd = struct
let get_by_service_username ~service ~username ?(custom_where=("",[])) db =
let q = "WHERE passwd.service=? AND passwd.username=?" in
let q = match custom_where with |"",_ -> q |w,_ -> q ^ " AND (" ^ w ^ ")" in
- let sql="SELECT passwd.id, passwd.service, passwd.ctime, passwd.username, passwd.encpasswd FROM passwd " ^ q in
+ let sql="SELECT passwd.id, passwd.service, passwd.ctime, passwd.username, passwd.encpasswd, passwd.comment FROM passwd " ^ q in
let stmt=Sqlite3.prepare db.db sql in
db_must_ok db (fun () -> let v = service in Sqlite3.bind stmt 1 (Sqlite3.Data.TEXT v));
db_must_ok db (fun () -> let v = username in Sqlite3.bind stmt 2 (Sqlite3.Data.TEXT v));
@@ -306,6 +324,11 @@ module Passwd = struct
|Sqlite3.Data.NULL -> failwith "null of_stmt"
|x -> Sqlite3.Data.to_string x)
)
+ ~comment:(
+ (match Sqlite3.column stmt 5 with
+ |Sqlite3.Data.NULL -> failwith "null of_stmt"
+ |x -> Sqlite3.Data.to_string x)
+ )
(* foreign fields *)
db
in
View
4 keychain_schema.mli
@@ -28,6 +28,8 @@ module Passwd : sig
set_username : string -> unit;
encpasswd : string;
set_encpasswd : string -> unit;
+ comment : string;
+ set_comment : string -> unit;
save: int64; delete: unit
>
@@ -40,6 +42,7 @@ module Passwd : sig
ctime:float ->
username:string ->
encpasswd:string ->
+ comment:string ->
Init.t -> t
(** Can be used to construct a new object. If [id] is not specified, it will be automatically assigned the first time [save] is called on the object. The object is not committed to the database until [save] is invoked. The [save] method will also return the [id] assigned to the object.
@raise Sql_error if a database error is encountered
@@ -51,6 +54,7 @@ module Passwd : sig
?ctime:float option ->
?username:string option ->
?encpasswd:string option ->
+ ?comment:string option ->
?custom_where:string * Sqlite3.Data.t list -> Init.t -> t list
(** Used to retrieve objects from the database. If an argument is specified, it is included in the search criteria (all fields are ANDed together).
@raise Sql_error if a database error is encountered
View
23 lifedb_dispatch.ml
@@ -81,8 +81,8 @@ let dispatch (lifedb : Lifedb_schema.Init.t) (syncdb : Sync_schema.Init.t) env (
let tasksel = if List.length url_list < 2 then "_all" else List.nth url_list 1 in
mark_get_rpc cgi;
Lifedb_tasks.dispatch cgi (match tasksel with
- |"_all" -> `List
- |name -> `Get name)
+ |"_all" -> `List
+ |name -> `Get name)
|`GET, "plugin" ->
let tasksel = if List.length url_list < 2 then "_all" else List.nth url_list 1 in
@@ -95,15 +95,24 @@ let dispatch (lifedb : Lifedb_schema.Init.t) (syncdb : Sync_schema.Init.t) env (
ignore(mark_post_rpc cgi);
if tasksel <> "_scan" then raise (Lifedb_rpc.Resource_not_found "unknown plugin request");
Lifedb_plugin.dispatch cgi `Scan
- |`POST, "passwd_create" ->
- let arg = mark_post_rpc cgi in
- Lifedb_passwd.dispatch cgi (`Store arg)
- |`POST, "passwd_delete" ->
+
+
+ |`POST, "passwd" ->
let arg = mark_post_rpc cgi in
- Lifedb_passwd.dispatch cgi (`Delete arg)
+ Lifedb_passwd.dispatch cgi (match url_list with
+ |[_; service; username] -> `Create (service, username, arg)
+ |_ -> raise (Lifedb_rpc.Invalid_rpc "need service/username")
+ )
+ |`DELETE, "passwd" ->
+ mark_delete_rpc cgi;
+ Lifedb_passwd.dispatch cgi (match url_list with
+ |[_; service; username] -> `Delete (service, username)
+ |_ -> raise (Lifedb_rpc.Invalid_rpc "need service/username")
+ )
|(`GET|`HEAD), "passwd" ->
mark_get_rpc cgi;
Lifedb_passwd.dispatch cgi (`Get (List.tl url_list))
+
|(`GET|`HEAD), "date" ->
mark_get_rpc cgi;
Lifedb_query.dispatch lifedb syncdb env cgi (`Date (List.tl url_list))
View
53 lifedb_passwd.ml
@@ -18,15 +18,17 @@
open Printf
open Utils
+open Lifedb_rpc
+
module KS = Keychain_schema
-let store_passwd db (ctime:float) service username passwd =
+let store_passwd db (ctime:float) service username passwd comment =
Log.logmod "Passwd" "Storing password for service=%s username=%s" service username;
match Passwords.encrypt_password ctime !Lifedb_rpc.passphrase passwd with
|Some encpasswd -> begin
let p = match KS.Passwd.get_by_service_username ~service ~username db with
- |[p] -> Log.logmod "Passwd" "editing"; p#set_ctime ctime; p#set_encpasswd encpasswd; p
- |[] -> Log.logmod "Passwd" "new entry"; KS.Passwd.t ~service ~username ~ctime ~encpasswd db
+ |[p] -> Log.logmod "Passwd" "editing"; p#set_ctime ctime; p#set_encpasswd encpasswd; p#set_comment comment; p
+ |[] -> Log.logmod "Passwd" "new entry"; KS.Passwd.t ~service ~username ~ctime ~encpasswd ~comment db
|_ -> assert false in
ignore(p#save)
end
@@ -35,7 +37,11 @@ let store_passwd db (ctime:float) service username passwd =
let get_passwd db service username =
Log.logmod "Passwd" "Password request for service=%s username=%s" service username;
match KS.Passwd.get_by_service_username ~service ~username db with
- |[p] -> Passwords.decrypt_password p#ctime !Lifedb_rpc.passphrase p#encpasswd
+ |[p] -> begin
+ match Passwords.decrypt_password p#ctime !Lifedb_rpc.passphrase p#encpasswd with
+ |None -> None
+ |Some encpasswd -> Some (encpasswd, p)
+ end
|_ -> None
let delete_passwd db service username =
@@ -45,7 +51,7 @@ let delete_passwd db service username =
|_ -> ()
type passwd_req =
- |Store of float * string * string * string
+ |Store of float * string * string * Lifedb.Rpc.Plugin.passwd_t
|Get of string * string
|Delete of string * string
@@ -61,8 +67,8 @@ let passwd_thread () =
while true do
let e = Event.sync (Event.receive creq) in
match e with
- |Store (time, service, username, password) ->
- store_passwd db time service username password
+ |Store (time, service, username, args) ->
+ store_passwd db time service username args#password args#comment
|Get (service, username) ->
let r = get_passwd db service username in
Event.sync (Event.send cresp r)
@@ -73,34 +79,27 @@ let passwd_thread () =
let init () =
let _ = Thread.create passwd_thread () in ()
-type json rpc_passwd_store = <
- service: string;
- username: string;
- password: string
->
-
-type json rpc_passwd_delete = <
- service: string;
- username: string
->
-
let dispatch (cgi:Netcgi.cgi_activation) = function
- |`Store arg -> begin
+ |`Create (svc, uname, arg) -> begin
let ctime = Unix.gettimeofday () in
- let params = rpc_passwd_store_of_json (Json_io.json_of_string arg) in
- Event.sync (Event.send creq (Store (ctime, params#service, params#username, params#password)))
+ let params = Lifedb.Rpc.Plugin.passwd_t_of_json (Json_io.json_of_string arg) in
+ Event.sync (Event.send creq (Store (ctime, svc, uname, params)))
end
- |`Delete arg -> begin
- let params = rpc_passwd_delete_of_json (Json_io.json_of_string arg) in
- Event.sync (Event.send creq (Delete (params#service, params#username)));
+ |`Delete (svc, uname) -> begin
+ Event.sync (Event.send creq (Delete (svc, uname)))
end
|`Get url_list -> begin
match url_list with
|[service; username] -> begin
match lookup_passwd service username with
- |Some encpasswd ->
- let resp = object method service=service method username=username method password=encpasswd end in
- cgi#output#output_string (Json_io.string_of_json (json_of_rpc_passwd_store resp))
+ |Some (encpasswd,args) ->
+ let resp = object
+ method service=service
+ method username=username
+ method password=encpasswd
+ method comment=args#comment
+ end in
+ cgi#output#output_string (Json_io.string_of_json (Lifedb.Rpc.Plugin.json_of_passwd_r resp))
|None ->
Lifedb_rpc.return_error cgi `Not_found "Passwd get error"
"Service/username not found"
View
1  lifedb_schema_generator.ml
@@ -90,6 +90,7 @@ let keychain = make [
date "ctime";
text "username";
text "encpasswd";
+ text "comment";
], [
[], ["service";"username"]
], { unique = [ [ "service"; "username" ] ] }
View
2  lifedb_tasks.ml
@@ -95,7 +95,7 @@ let run_command name cmd cwd secret args silo =
let env = match secret with |None -> [||]
|Some (s,u) -> begin
match Lifedb_passwd.lookup_passwd s u with
- |Some p -> [| ("LIFEDB_PASSWORD=" ^ p); ("LIFEDB_USERNAME="^u) |]
+ |Some (pass, _) -> [| ("LIFEDB_PASSWORD=" ^ pass); ("LIFEDB_USERNAME="^u) |]
|None -> Log.logmod "Tasks" "WARNING: unable to find passwd for this task"; [||]
end
in
Please sign in to comment.
Something went wrong with that request. Please try again.