User talk:Caveman

From AOLserver Wiki
Jump to navigation Jump to search

towards a data and authentication layer

It is possible that similar exists elsewhere (non-OpenACS) but I enjoy framework construction anyway. Services provided:

  1. authentication (password check)
  2. sequences
  3. data layer

Authentication/Authorization config (nsz):

# config: "/security/password/expression"
# {::sha1::hmac [lindex $args 1] [lindex $args 0]}
# config: "/security/password/query"
# {select password, salt from users where name=[ns_dbquotevalue [lindex $args 0]]}
# config: "/security/salt/length" "64"
# config: "/security/salt/dictionary" "0123456789abcdefghijkl..."

Basically the "expression" is used in a function, nsz_password to format a given clear-text password (varargs "args" to allow additional arguments to the function). The first argument is always the password.

The "query" is executed as part of password-based authentication. The form handler reaches nsz_auth "myname" "mypassword" and the query is executed using the input list "myname". All row data beyond the first column, which must always be the password, is appended to the input password "mypassword" to produce the hash/salted/hash input "xpassword". This input "xpassword" is compared with the result of the returned value for the first column from the database query. If there is a match, password authentication succeeds for the user.


nsz_auth "sam" "correctpassword"
# Query returns "sadf8vcx8vxasd7f7...","asduf7z6dfa..."
# Expression eval for input passes "correctpassword","asduf7z6dfa..." and returns "sadf8vcx8vxasd7f7..."
# Return value matches query
# nsz_auth returns "sam"

nsz_auth "sam" "badpassword"
# Query returns "sadf8vcx8vxasd7f7...","asduf7z6dfa..."
# Expression eval for input passes "badpassword","asduf7z6dfa..." and returns "yyzkfosd232cx7c..."
# Return value does not match query
# nsz_auth raises error "bad password"

Different configurations could use simple clear-text passwords, no salt, etc, simply by changing their configuration:

# config: "nsz/security/password/expression"
# {lindex $args 0}
# config: "nsz/security/password/query"
# {select password from users where name=[ns_dbquotevalue [lindex $args 0]]}

The above would be the default configuration. For salt, the default would be size of 8 and dictionary of alphanumerics.

Function nsz_salt can take 0, 1, or 2 arguments and returns the generated salt. The first argument is the length of the salt, defaults to config value. The second argument is the dictionary for the salt, default to config value.

Question: How to make "users" table configurable? What about configuring which database pool to use? What about multiple authentication realms?

Sequences configuration should be as simple as specifying the database pool to use (default by default), the name of the sequence table, the size of the sequence chunk to claim when the local cache runs out of sequence numbers, and the number of retries before error during chunk claim. It could however be more complex, to specify the column names for the "name" and "value" of the sequence.


# config: "nso/sequence/default/poolname" (default by default)
# config: "nso/sequence/default/size" "100"
# config: "nso/sequence/default/retry" "5"
# config: "nso/sequence/default/table" "sequences_table"
# config: "nso/sequence/default/name" "name_field"
# config: "nso/sequence/default/value" "value_field"

Sequence defaults could be over-written per-sequence in similar fashion.

Example usage:

set nextId [nso_sequence next "my_seq_name"]
# returns 53 or error if fail

The function nso_sequence would thread-safe return the next sequence number it had available in its local nsv data, or if not available, claim the next chunk of 100 sequences numbers from the database:

# select value_field from sequences_table where name_field='my_seq_name'
# result is 125, attempt to claim 100 values
# update cave_sequences set value=225 where name_field='my_seq_name' and value_field=125

This would be retried up to 5 times.

Data layer notes:

Config would map names like "users" to database pools and table names. Default would be default database pool and identity table name.

Example usage:

# set nssValues [ns_set create]
# ns_set update $nssValues "name" "sam"
# ns_set update $nssValues "password" "mypassword"
# ns_set put $nssValues "mail" ""
# set nssUserKey [nso_row create "users" $nssValues]
# set nssNewValues [ns_set create]
# ns_set put $nssNewValues "mail" ""
# nso_row update "users" $nssUserKey $nssNewValues

Using ns_set instead of a model type-checking "nso_set" at least for now for simplicity and it would be the simple case.

Additional config allows for data transforms:

# multi stage of filters and expressions:
# stage 0: accept-data-filter
#   e.g. "require a password is not null"
#   e.g. "require this integer be above zero"
#   e.g. "require id not be set"
# stage 1: transform-data-filter
# config: expressions to apply to row:
#   e.g. "generate a salt"
#     ns_set update $nssData "salt" [nsz_salt]
#   e.g. "transform the password"
#     ns_set update $nssData "password" [nsz_password [ns_set get $nssData "password"] [ns_set get $nssData "salt"]]
#   e.g. "generate the next id from sequence"
#     ns_set update $nssData "id" [nso_sequence next "my_seq_name"]
# stage 2: veto-data-filter?
# allow multiple "inheritance" of data rules? or just defining rules that
# can be referenced by multiple tables?

very draft state

useful links


AJAX/JSON support in AOLserver

  1. HTTP request hits AOLserver, returns HTML including JavaScript with AJAX (or JSON-RPC, whatever) features.
  2. Client interacts with rendered HTML application, resulting in AJAX calls to AOLserver.
  3. AOLserver handles the AJAX calls and responds.
  4. Client potentially modified by result of AJAX call without reload.

Use cases:

  1. Rate something and store the rating without reload of page.
  2. Stateful drag and drop of tiles (shopping cart, wish list).
  3. Background saving of application state (e.g. word processor, calendar, etc) without page reload.
  4. Reload portions of the view (e.g. portlet) without reloading the whole page. E.g. stock tickers, chat windows, log viewers, etc.
  5. Add/remove item from cart statefully without reload of page.
  6. Recalculate shopping cart prices/totals without reload of page.


  1. Allows "Web 2.0" sites such as Digg and Gmail to be run on massively scalable AOLserver platform.
  2. It's an itch. We scratch these things.


Sysop and Bureaucrat rights

Hi, Sam - I've granted you Sysop and Bureaucrat rights, so you can delete wiki pages and such. You seem to watch the wiki and police it for spam a lot more than I can these days. Thanks! -- Dossy 16:50, 20 October 2009 (EDT)