Generating UNIX passwords
[hcoop/zz_old/portal.git] / app / app.sml
index 62f386a..1346829 100644 (file)
@@ -1,7 +1,7 @@
 structure App :> APP =
 struct
 
-val baseUrl = "http://join.hcoop.net/join/"
+val baseUrl = "https://join.hcoop.net/join/"
 val portalUrl = "https://members2.hcoop.net/portal/"
 
 open Sql
@@ -95,6 +95,18 @@ fun sendMail (to, subj, intro, footer, id) =
 type application = { name : string, rname : string, gname : string option, email : string,
                     forward : bool, uses : string, other : string }
 
+fun randomPassword () =
+    let
+       val proc = Unix.execute ("/usr/bin/apg", ["/usr/bin/apg", "-n", "1", "-m", "10"])
+    in
+       case TextIO.inputLine (Unix.textInstreamOf proc) of
+           NONE => raise Fail "Couldn't execute apg"
+         | SOME line =>
+           case String.tokens Char.isSpace line of
+               [s] => s
+             | _ => raise Fail "Couldn't parse output of apg"
+    end
+
 fun apply {name, rname, gname, email, forward, uses, other} =
     let
        val db = getDb ()
@@ -104,22 +116,24 @@ fun apply {name, rname, gname, email, forward, uses, other} =
            let
                val id = C.intFromSql id
                val passwd = Int.toString (Int.abs (Random.randInt (!rnd)))
+               val unix_passwd = randomPassword ()
            in
-               C.dml db ($`INSERT INTO MemberApp (id, name, rname, gname, email, forward, uses, other, passwd, status, applied, msg)
+               C.dml db ($`INSERT INTO MemberApp (id, name, rname, gname, email, forward, uses, other, passwd, status, applied, msg, unix_passwd)
                            VALUES (^(C.intToSql id), ^(C.stringToSql name), ^(C.stringToSql rname),
                                    ^(case gname of NONE => "NULL" | SOME gname => C.stringToSql gname),
                                    ^(C.stringToSql email), ^(C.boolToSql forward), ^(C.stringToSql uses),
-                                   ^(C.stringToSql other), ^(C.stringToSql passwd), 0, CURRENT_TIMESTAMP, '')`);
+                                   ^(C.stringToSql other), ^(C.stringToSql passwd), 0, CURRENT_TIMESTAMP,
+                                   '', ^(C.stringToSql unix_passwd))`);
                sendMail (email, "Confirm membership application",
-                         "We've received a request to join the Internet Hosting Cooperative (hcoop.net) with this e-mail address.",
+                            "We've received a request to join the Internet Hosting Cooperative (hcoop.net) with this e-mail address.",
                          fn mwrite => (mwrite ("To confirm this application, visit ");
                                        mwrite (baseUrl);
                                        mwrite ("confirm?id=");
                                        mwrite (Int.toString id);
                                        mwrite ("&p=");
-                                       mwrite (passwd);
+                                       mwrite passwd;
                                        mwrite ("\n")),
-                         id)
+                            id)
            end
       | _ => raise Fail "Bad next sequence val"
     end
@@ -154,17 +168,20 @@ fun confirm (id, passwd) =
     let
        val db = getDb ()
     in
-       case C.oneOrNoRows db ($`SELECT id FROM MemberApp WHERE id = ^(C.intToSql id) AND passwd = ^(C.stringToSql passwd) AND status = 0`) of
-           SOME _ =>
+       case C.oneOrNoRows db ($`SELECT unix_passwd FROM MemberApp WHERE id = ^(C.intToSql id) AND passwd = ^(C.stringToSql passwd) AND status = 0`) of
+           SOME [unix_passwd] =>
            (C.dml db ($`UPDATE MemberApp SET status = 1, confirmed = CURRENT_TIMESTAMP WHERE id = ^(C.intToSql id)`);
-            sendMail ("board@hcoop.net",
-                      "New membership application",
-                      "We've received a new request to join hcoop.",
+            if sendMail ("board@hcoop.net",
+                         "New membership application",
+                         "We've received a new request to join hcoop.",
                       fn mwrite => (mwrite ("Open applications: ");
                                     mwrite (portalUrl);
                                     mwrite ("apps")),
-                      id))
-         | NONE => false
+                         id) then
+                SOME (C.stringFromSql unix_passwd)
+            else
+                NONE)
+         | NONE => NONE
     end
 
 end