----------------------
Implementation Details
----------------------

The Swauth system is a scalable authentication and authorization system that
uses Swift itself as its backing store. This section will describe how it
stores its data.

.. note::

    You can access Swauth's internal .auth account by using the account:user of
    .super_admin:.super_admin and the super admin key you have set in your
    configuration. Here's an example using `st` on a standard SAIO: ``st -A
    http://127.0.0.1:8080/auth/v1.0 -U .super_admin:.super_admin -K swauthkey
    stat``

At the topmost level, the auth system has its own Swift account it stores its
own account information within. This Swift account is known as
self.auth_account in the code and its name is in the format
self.reseller_prefix + ".auth". In this text, we'll refer to this account as
<auth_account>.

The containers whose names do not begin with a period represent the accounts
within the auth service. For example, the <auth_account>/test container would
represent the "test" account.

The objects within each container represent the users for that auth service
account. For example, the <auth_account>/test/bob object would represent the
user "bob" within the auth service account of "test". Each of these user
objects contain a JSON dictionary of the format::

    {"auth": "<auth_type>:<auth_value>", "groups": <groups_array>}

The `<auth_type>` specifies how the user key is encoded. The default is `plaintext`, 
which saves the user's key in plaintext in the `<auth_value>` field.
The value `sha1` is supported as well, which stores the user's key as a salted
SHA1 hash. Note that using a one-way hash like SHA1 will likely inhibit future use of key-signing request types, assuming such support is added. The `<auth_type>` can be specified in the swauth section of the proxy server's 
config file, along with the salt value in the following way::

    auth_type = <auth_type>
    auth_type_salt = <salt-value>

Both fields are optional. auth_type defaults to `plaintext` and auth_type_salt defaults to "swauthsalt". Additional auth types can be implemented along with existing ones in the authtypes.py module.

The `<groups_array>` contains at least two groups. The first is a unique group
identifying that user and it's name is of the format `<user>:<account>`. The
second group is the `<account>` itself. Additional groups of `.admin` for
account administrators and `.reseller_admin` for reseller administrators may
exist. Here's an example user JSON dictionary::

    {"auth": "plaintext:testing",
     "groups": [{"name": "test:tester"}, {"name": "test"}, {"name": ".admin"}]}

To map an auth service account to a Swift storage account, the Service Account
Id string is stored in the `X-Container-Meta-Account-Id` header for the
<auth_account>/<account> container. To map back the other way, an
<auth_account>/.account_id/<account_id> object is created with the contents of
the corresponding auth service's account name.

Also, to support a future where the auth service will support multiple Swift
clusters or even multiple services for the same auth service account, an
<auth_account>/<account>/.services object is created with its contents having a
JSON dictionary of the format::

    {"storage": {"default": "local", "local": <url>}}

The "default" is always "local" right now, and "local" is always the single
Swift cluster URL; but in the future there can be more than one cluster with
various names instead of just "local", and the "default" key's value will
contain the primary cluster to use for that account. Also, there may be more
services in addition to the current "storage" service right now.

Here's an example .services dictionary at the moment::

    {"storage":
        {"default": "local",
         "local": "http://127.0.0.1:8080/v1/AUTH_8980f74b1cda41e483cbe0a925f448a9"}}

But, here's an example of what the dictionary may look like in the future::

    {"storage":
        {"default": "dfw",
         "dfw": "http://dfw.storage.com:8080/v1/AUTH_8980f74b1cda41e483cbe0a925f448a9",
         "ord": "http://ord.storage.com:8080/v1/AUTH_8980f74b1cda41e483cbe0a925f448a9",
         "sat": "http://ord.storage.com:8080/v1/AUTH_8980f74b1cda41e483cbe0a925f448a9"},
     "servers":
        {"default": "dfw",
         "dfw": "http://dfw.servers.com:8080/v1/AUTH_8980f74b1cda41e483cbe0a925f448a9",
         "ord": "http://ord.servers.com:8080/v1/AUTH_8980f74b1cda41e483cbe0a925f448a9",
         "sat": "http://ord.servers.com:8080/v1/AUTH_8980f74b1cda41e483cbe0a925f448a9"}}

Lastly, the tokens themselves are stored as objects in the
`<auth_account>/.token_[0-f]` containers. The names of the objects are the
token strings themselves, such as `AUTH_tked86bbd01864458aa2bd746879438d5a`.
The exact `.token_[0-f]` container chosen is based on the final digit of the
token name, such as `.token_a` for the token
`AUTH_tked86bbd01864458aa2bd746879438d5a`. The contents of the token objects
are JSON dictionaries of the format::

    {"account": <account>,
     "user": <user>,
     "account_id": <account_id>,
     "groups": <groups_array>,
     "expires": <time.time() value>}

The `<account>` is the auth service account's name for that token. The `<user>`
is the user within the account for that token. The `<account_id>` is the
same as the `X-Container-Meta-Account-Id` for the auth service's account,
as described above. The `<groups_array>` is the user's groups, as described
above with the user object. The "expires" value indicates when the token is no
longer valid, as compared to Python's time.time() value.

Here's an example token object's JSON dictionary::

    {"account": "test",
     "user": "tester",
     "account_id": "AUTH_8980f74b1cda41e483cbe0a925f448a9",
     "groups": [{"name": "test:tester"}, {"name": "test"}, {"name": ".admin"}],
     "expires": 1291273147.1624689}

To easily map a user to an already issued token, the token name is stored in
the user object's `X-Object-Meta-Auth-Token` header.

Here is an example full listing of an <auth_account>::

    .account_id
        AUTH_2282f516-559f-4966-b239-b5c88829e927
        AUTH_f6f57a3c-33b5-4e85-95a5-a801e67505c8
        AUTH_fea96a36-c177-4ca4-8c7e-b8c715d9d37b
    .token_0
    .token_1
    .token_2
    .token_3
    .token_4
    .token_5
    .token_6
        AUTH_tk9d2941b13d524b268367116ef956dee6
    .token_7
    .token_8
        AUTH_tk93627c6324c64f78be746f1e6a4e3f98
    .token_9
    .token_a
    .token_b
    .token_c
    .token_d
    .token_e
        AUTH_tk0d37d286af2c43ffad06e99112b3ec4e
    .token_f
        AUTH_tk766bbde93771489982d8dc76979d11cf
    reseller
        .services
        reseller
    test
        .services
        tester
        tester3
    test2
        .services
        tester2
