_Handin Server and Client_ The "handin-server" directory contains a server to be run by a course instructor for accepting homework assignments and reporting on submitted assignments. The "handin-client" directory contains a client to be customized then re-distributed to students in the course. The customized client will embed a particular hostname and port where the server is running, as well as a server certificate. With a customized client, students simply install a ".plt" file --- so there's no futzing with configuration dialogs and certificates. A student can install any number of clients at once (assuming that the clients are properly customized, as described below). The result, on the student's side, is a "Handin" button in DrScheme's toolbar. Clicking the "Handin" button allows the student to type a password and upload the current content of the definitions and interactions window to the course instructor's server. The "File" menu is also extended with a "Manage..." menu item for managing a handin account (i.e., changing the password and other information, or creating a new account if the instructor configures the server to allow new accounts). Students can submit joint work by submitting with a concatenation of usernames separated by a "+". On the instructor's side, the handin server can be configured to check the student's submission before accepting it. The handin process uses SSL, so it is effectively as secure as the server and each user's password. Quick Start for a Test Drive: ============================= 1. Create a new directory. 2. Copy "server-cert.pem" from the "handin-client" collection to the new directory. NOTE: for real use, you need a new certificate. NOTE: see also "Where is the collection?", below 3. Copy "private-key.pem" from the "handin-server" collection to the new directory. NOTE: for real use, you need a new key. 4. Create a file "users.ss" with the following content: ((tester ("8fe4c11451281c094a6578e6ddbf5eed"))) 5. Make a "test" subdirectory in your new directory. 6. Create a file "config.ss" with the following content: ((active-dirs ("test"))) 7. In your new directory, run mred -mvqM handin-server 8. In the "handin-client" collection, edit "info.ss" and uncomment the line (define server:port "localhost:7979") and the lines that define `tools', `tool-names', and `tool-icons'. 9. Run `setup-plt -l handin-client' (on Windows, the executable is "Setup PLT", and you don't have to supply the command line arguments). 10. Start DrScheme, click "Handin" to run the client, submit with username "tester" and password "pw". The submitted file will be .../test/tester/handin.scm. 11. Check the status of your submission by pointing a web browser at https://localhost:7980/servlets/status.ss Note the "s" in "https". Use the "tester" username and "pw" password, as before. ------------------------------------------------------------------- | "Where is the collection?" | |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -| | If you obtained the server and client by installing a .plt file, | | then the "handin-server" and "handin-client" directories | | might be in your PLT addon space. Start MzScheme, and enter | | (collection-path "handin-server") | | (collection-path "handin-client") | | to find out where these collections are. | ------------------------------------------------------------------- Client Customization: ===================== 1. Rename (or make a copy of) the "handin-client" collection directory. The new name should describe your class uniquely. For example, "uu-cpsc2010" is a good name for CPSC 2010 at the University of Utah. 2. Edit the first three definitions of "info.ss" in your renamed client collection: * For `name', choose a name for the handin tool as it will appear in DrScheme's interface (e.g., the "XXX" for the "Manage XXX Handin Account..." menu item). Again, make the name specific to the course, in case a student installs multiple handin tools. Do not use "Handin" as the last part of the name, since "Handin" is always added for button and menu names. * For `server:port', uncomment the line, and use the hostname and port where the server will be running to accept handin submissions. Optionally uncomment and edit the next two definitions, `web-menu-name' and `web-address', to add an item to the "Help" menu that opens a (course-specific) web page. 3. Replace "icon.png" in your renamed directory with a new 32x32 icon. This icon is displayed on startup with DrScheme's splash screen, and it is included at half size on the "Handin" button. Again, choose a distinct icon for the benefit of students who install multiple handin tools. A school logo is typically useful, as it provides a recognizably local visual cue. 4. Replace "server-cert.pem" in your renamed directory with a server certificate. The file "server-cert.pem" in "handin-client" collection is ok for testing, but the point of this certificate is to make handins secure, so you should generate a new (self-certifying) certificate and keep its key private. (See server setup, below.) 5. Run mzc --collection-plt .plt where is the name that you chose for your directory (i.e., whatever you changed "handin-client" to). 6. Distribute .plt to students for installation into their copies of DrScheme. The students need not have access to the DrScheme installation directory; the tool will be installed on the filesystem in the student's personal space. If you want to install it once on a shared installation, use setup-plt with the --all-users flag. Server Setup: ============= You must prepare a special directory to host the handin server. To run the server, you should either be in this directory, or you should set the "PLT_HANDINSERVER_DIR" environment variable. This directory contains the following files and sub-directories: * "server-cert.pem" --- the server's certificate. To create a certificate and key with openssl: openssl req -new -nodes -x509 -days 365 -out server-cert.pem -keyout private-key.pem * "private-key.pem" --- the private key to go with "server-cert.pem". Whereas "server-cert.pem" gets distributed to students with the handin client, "private-key.pem" is kept private. * "config.ss" --- configuration options. The file format is (( ) ...) The following keys can be used (without the preceding quote): 'active-dirs : a list of directories that are active submissions, relative to the current directory or absolute; the last path element for each of these (and 'inactive-dirs below) should be unique, and is used to identify the submission (for example, in the client's submission dialog and in the status servlet) 'inactive-dirs : a list of inactive submission directories (see above for details) 'port-number : the port for the main handin server; the default is 7979 'https-port-number : the port for the handin-status HTTPS server; the default is one more than the main server's port (so the transitive default is 7980) 'session-timeout : number of seconds before the session times-out -- the client is given this many seconds for the login stage and then starts again so the same number of seconds is given for the submit-validation process; the default is 300 'session-memory-limit : maximum size in bytes of memory allowed for per-session computation, if per-session limits are supported (i.e., when using MrEd3m and MzScheme3m with memory accounting); the default is 40000000 'default-file-name : the default filename that will be saved with the submission contents. The default is "handin.scm". 'max-upload : maximum size in bytes of an acceptable submission; the default is 500000 'max-upload-keep : maximum index of submissions to keep; the most recent submission is "handin.scm" (by default), the next oldest is in "BACKUP-0/handin.scm", next oldest is "BACKUP-1/handin.scm", etc.; the default is 9 'user-regexp : a regular expression that is used to validate usernames; alternatively, this can be `#f' meaning no restriction, or a list of permitted strings. Young students often choose exotic usernames that are impossible to remember, and forget capitalization, so the default is fairly strict: #rx"^[a-z][a-z0-9]+$"; a "+" is always disallowed in a username, since it is used in a submission username to specify joint work 'user-desc : a plain-words description of the acceptable username format (according to user-regexp above); `#f' stands for no description; the default is "alphanumeric string" which matches the default user-regexp 'username-case-sensitive : a boolean; when `#f', usernames are case-folded for all purposes; defaults to `#f' (note that you should not set this to `#t' on Windows or when using other case-insensitive filesystems, since usernames are used as directory names) 'allow-new-users : a boolean indicating whether to allow new-user requests from a client tool; the default is `#f' 'allow-change-info : a boolean indicating whether to allow changing user information from a client tool (changing passwords is always possible); the default is `#f' 'master-password : a string for an MD5 hash for a password that allows login as any user; the default is `#f', which disables the password 'log-output : a boolean that controls whether the handin server log is written on the standard output; defaults to `#t' 'log-file : a path (relative to handin server directory or absolute) that specifies a filename for the handin server log (possibly combined with the 'log-output option), or `#f' for no log file; defaults to "log" 'web-base-dir : if `#f' (the default), the built-in web server will use the "status-web-root" in this collection for its configuration; to have complete control over the built in server, you can copy and edit "status-web-root", and add this configuration entry with the name of your new copy (relative to the handin server directory, or absolute) 'web-log-file : a path (relative to handin server directory or absolute) that specifies a filename for logging the internal HTTPS status web server; or `#f' (the default) to disable this log 'extra-fields : a list that describes extra string fields of information for student records; each element in this list is a list of three values -- the name of the field, the regexp (or `#f', or a list of permitted string values), and a string describing of acceptable strings. The default is '(("Full Name" #f #f) ("ID#" #f #f) ("Email" #rx"^[^@<>\"`',]+@[a-zA-Z0-9_.-]+[.][a-zA-Z]+$" "a valid email address")) You can set this to a list of fields that you are interested in keeping, for example: '(("Full Name" #rx"^[A-Z][a-zA-Z]+(?: [A-Z][a-zA-Z]+)+$" "full name, no punctuations, properly capitalized") ("Utah ID Number" #rx"^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$" "Utah ID Number with exactly nine digits") ("Email" #rx"^[^@<>\"`',]+@cs\\.utah\\.edu$" "A Utah CS email address")) The order of these fields will be used both on the client GUI side and in the "users.ss" file (see below). The second item in a field description can also be the symbol '-, which marks this field as one that is hidden from the user interface: students will not see it and will not be able to provide or modify it; when a new student creates an account, such fields will be left empty. This is useful for adding information that you have on students from another source, for example, adding information from a course roster. You should manually edit the "users.ss" file and fill in such information. (The third element for such descriptors is ignored.) 'hook-file : a path (relative to handin server directory or absolute) that specifies a filename that contains a `hook' module. This is useful as a general device for customizing the server through Scheme code. The file is expected to contain a module that provides a `hook' function, which should be receiving three arguments: - a symbol that indicates the operation that is now taking place; - a datum that specifies the connection context (a number for handin connections, a `wN' symbol for servlet connections, and #f for other server operations); - an alist of information relevant to this operation. Currently, the hook is used in several places after an operation has completed. The first argument will be one of these symbols: 'server-start, 'server-connect, 'user-create, 'user-change, 'login, 'submission-received, 'submission-committed, 'submission-retrieved, 'status-login, 'status-file-get. For example, here is a simple hook module that sends notification messages when users are created or their information has changed: (module hook mzscheme (provide hook) (require (lib "sendmail.ss" "net")) (define (hook what session alist) (when (memq what '(user-create user-change)) (send-mail-message "course-staff@university.edu" (format "[server] ~a (~a)" what session) '("course-staff@university.edu") '() '() (map (lambda (key+val) (apply format "~a: ~s" key+val)) alist))))) Changes to "config.ss" are detected, the file will be re-read, and options are reloaded. A few options are fixed at startup time: port numbers, log file specs, and the `web-base-dir' are as configured at startup. All other options will change the behavior of the running server (but things like `username-case-sensitive?' it would be unwise to do so). (For safety, options are not reloaded until the file parses correctly, but make sure that you don't save a copy that has inconsistent options: it is best to create a new configuration file and move it over the old one, or use an editor that does so and not save until the new contents is ready.) This is most useful for closing & openning submission directories. * "users.ss" (created if not present if a user is added) --- keeps the list of user accounts, along with the associated password (actually the MD5 hash of the password), and extra string fields as specified by the 'extra-fields configuration entry (in the same order). The file format is (( ( ...)) ...) For example, the default 'extra-field setting will make this: (( ( )) ...) Username that begin with "solution" are special. They are used by the HTTPS status server. Independent of the 'user-regexp and 'username-case-sensitive? configuration items, usernames are not allowed to contain characters that are illegal in Windows pathnames, they cannot end or begin in spaces or periods. If the 'allow-new-users configuration allows new users, the "users.ss" file can be updated by the server with new users. It can always be updated by the server to change passwords. If you have access to a standard Unix password file (from "/etc/passwd" or "/etc/shadow"), then you can construct a "users.ss" file that will allow users to use their normal passwords. To achieve this, use a list with 'unix as the first element and the system's encrypted password string as the second element. Such passwords can be used, but when users change them, a plain md5 hash will be used. You can combine this with other fields from the password file to create your "users.ss", but make sure you have information that matches your 'extra-fields specification. For example, given this system file: foo:wRzN1u5q2SqRD:1203:1203:L.E. Foo:/home/foo:/bin/tcsh bar:$1$dKlU0OkJ$t63TzKz:1205:1205:Bar Z. Lie:/home/bar:/bin/bash you can create this "users.ss" file: ((foo ((unix "wRzN1u5q2SqRD") "L.E. Foo" "?")) (bar ((unix "$1$dKlU0OkJ$t63TzKz") "Bar Z. Lie" "?"))) which can be combined with this setting for 'extra-fields in your "config.ss": ... (extra-fields (("Full Name" #f #f) ("TA" '("Alice" "Bob") "Your TA"))) ... and you can tell your students to use their department username and password, and use the "Manage ..." dialog to properly set their TA name. Finally, a password value can be a list that begins with a 'plaintext symbol, which will be used without encryption. This may be useful for manually resetting a forgotten passwords. * "log" (or any other name that the 'log-file configuration option specifies (if any), created if not present, appended otherwise) --- records connections and actions, where each entry is of the form (id time-str msg-str) [|