Skip to content

Commit b4db3db

Browse files
MNassimMPlictox
andcommitted
feat(state): Store session-token links using Irmin instead of JSON file
Replace the JSON-based storage of session-token-date entries with an Irmin Git-backed key-value store. Sessions are no longer stored in 'sessions.json' but in an Irmin Git repository ('session_store.git' by default). Credits: this patch reuses code from oauth-moodle-dev by the following authors. Co-authored-by: Louis Tariot <[email protected]>
1 parent a669c98 commit b4db3db

File tree

3 files changed

+42
-47
lines changed

3 files changed

+42
-47
lines changed

src/state/dune

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,5 @@
4040
(name learnocaml_store)
4141
(wrapped false)
4242
(modules Learnocaml_store)
43-
(libraries cryptokit lwt_utils learnocaml_api)
43+
(libraries cryptokit lwt_utils learnocaml_api irmin irmin-git irmin-git.unix)
4444
)

src/state/learnocaml_store.ml

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -302,50 +302,50 @@ end
302302
module Session = struct
303303

304304
include Session
305+
open Lwt.Syntax
305306

306-
let file = "sessions.json"
307+
module Store = Irmin_git_unix.FS.KV(Irmin.Contents.Json_value)
308+
module Info = Irmin_git_unix.Info(Store.Info)
307309

308-
let enc =
309-
let open Json_encoding in
310-
list (obj3
311-
(req "session" Session.enc)
312-
(req "token" Token.enc)
313-
(req "last_connection" float))
314-
315-
let path dir = Filename.concat dir file
316-
317-
let load dir =
318-
let p = path dir in
319-
Lwt_unix.file_exists dir >>= fun dir_exists ->
320-
(if not dir_exists then Lwt_unix.mkdir dir 0o700 else Lwt.return_unit) >>= fun () ->
321-
Lwt_unix.file_exists p >>= function
322-
| false ->
323-
Printf.printf "No session file, creating empty list\n%!";
324-
Lwt.return []
325-
| true ->
326-
Printf.printf "Loading sessions from: %s\n%!" p;
327-
get_from_file enc p
310+
let repo_path = ref "./session_store.git"
328311

329-
let save dir table =
330-
write_to_file enc table (path dir)
312+
let config () = Irmin_git.config ~bare:true !repo_path
331313

332-
let get_user_token session =
333-
load !data_dir >>= fun table ->
334-
match List.find_opt (fun (s, _, _) -> s = session) table with
335-
| Some (_, token, _) -> Lwt.return_some token
336-
| None -> Lwt.return_none
314+
type entry = {
315+
session : Session.t;
316+
token : Token.t;
317+
last_connection : float;
318+
}
319+
320+
let enc =
321+
let open Json_encoding in
322+
conv
323+
(fun {session; token; last_connection} -> (session, token, last_connection))
324+
(fun (session, token, last_connection) -> {session; token; last_connection})
325+
(obj3
326+
(req "session" Session.enc)
327+
(req "token" Token.enc)
328+
(req "last_connection" float))
337329

338330
let set_session session token =
339331
let now = Unix.gettimeofday () in
340-
load !data_dir >>= fun table ->
341-
let table = (session, token, now) :: table in
342-
save !data_dir table
332+
let* repo = Store.Repo.v (config ()) in
333+
let* t = Store.main repo in
334+
Store.set_exn t ~info:(Info.v "Set session/token") [Session.to_string session] (Json_encoding.construct enc {session; token; last_connection = now})
335+
336+
let get_user_token session =
337+
let* repo = Store.Repo.v (config ()) in
338+
let* t = Store.main repo in
339+
Store.find t [Session.to_string session] >|= function
340+
| Some value ->
341+
let entry = Json_encoding.destruct enc value in
342+
Some entry.token
343+
| None -> None
343344

344345
let gen_session () =
345346
let len = 32 in
346347
Cryptokit.Random.string Cryptokit.Random.secure_rng len
347-
|> Cryptokit.transform_string @@ Cryptokit.Hexa.encode ()
348-
348+
|> Cryptokit.transform_string @@ Cryptokit.Hexa.encode ()
349349
end
350350

351351
module Token = struct

src/state/learnocaml_store.mli

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -116,26 +116,21 @@ module Session: sig
116116

117117
include module type of struct include Session end
118118

119-
val file : string
120-
121-
val enc : (t * Token.t * float) list Json_encoding.encoding
122-
123-
val path : string -> string
124-
125-
(** Loads the session table from disk. *)
126-
val load : string -> (t * Token.t * float) list Lwt.t
127-
128-
(** Saves the given session table to disk *)
129-
val save : string -> (t * Token.t * float) list -> unit Lwt.t
119+
type entry = {
120+
session : Session.t;
121+
token : Token.t;
122+
last_connection : float;
123+
}
124+
val enc : entry Json_encoding.encoding
130125

131126
(** Retrieves the token associated with the given session. *)
132127
val get_user_token : t -> Token.t option Lwt.t
133128

134129
(** Associates a token to a session. *)
135130
val set_session : t -> Token.t -> unit Lwt.t
136131

137-
(** Generates a fresh session identifier *)
138-
val gen_session : unit -> t
132+
(** Generates a fresh session identifier *)
133+
val gen_session : unit -> Session.t
139134
end
140135

141136

0 commit comments

Comments
 (0)