function new_access_token($token, $consumer, $verifier = null) { common_debug(sprintf("New access token from request token %s, consumer %s and verifier %s ", $token, $consumer, $verifier), __FILE__); $rt = new Token(); $rt->consumer_key = $consumer->key; $rt->tok = $token->key; $rt->type = 0; // request $app = Oauth_application::getByConsumerKey($consumer->key); assert(!empty($app)); if ($rt->find(true) && $rt->state == 1 && $rt->verifier == $verifier) { // authorized common_debug('Request token found.', __FILE__); // find the app and profile associated with this token $tokenAssoc = Oauth_token_association::getKV('token', $rt->tok); if (!$tokenAssoc) { throw new Exception(_('Could not find a profile and application associated with the request token.')); } // Check to see if we have previously issued an access token for // this application and profile; if so we can just return the // existing access token. That seems to be the best practice. It // makes it so users only have to authorize the app once per // machine. $appUser = new Oauth_application_user(); $appUser->application_id = $app->id; $appUser->profile_id = $tokenAssoc->profile_id; $result = $appUser->find(true); if (!empty($result)) { common_log(LOG_INFO, sprintf("Existing access token found for application %s, profile %s.", $app->id, $tokenAssoc->profile_id)); $at = null; // Special case: we used to store request tokens in the // Oauth_application_user record, and the access_type would // always be 0 (no access) as a failsafe until an access // token was issued and replaced the request token. There could // be a few old Oauth_application_user records storing request // tokens still around, and we don't want to accidentally // return a useless request token instead of a new access // token. So if we find one, we generate a new access token // and update the existing Oauth_application_user record before // returning the new access token. This should be rare. if ($appUser->access_type == 0) { $at = $this->generateNewAccessToken($consumer, $rt, $verifier); $this->updateAppUser($appUser, $app, $at); } else { $at = new Token(); // fetch the full access token $at->consumer_key = $consumer->key; $at->tok = $appUser->token; $result = $at->find(true); if (!$result) { throw new Exception(_('Could not issue access token.')); } } // Yay, we can re-issue the access token return new OAuthToken($at->tok, $at->secret); } else { common_log(LOG_INFO, sprintf("Creating new access token for application %s, profile %s.", $app->id, $tokenAssoc->profile_id)); $at = $this->generateNewAccessToken($consumer, $rt, $verifier); $this->newAppUser($tokenAssoc, $app, $at); // Okay, good return new OAuthToken($at->tok, $at->secret); } } else { // the token was not authorized or not verfied common_log(LOG_INFO, sprintf("API OAuth - Attempt to exchange unauthorized or unverified request token %s for an access token.", $rt->tok)); return null; } }
function new_access_token($token, $consumer, $verifier) { common_debug(sprintf("New access token from request token %s, consumer %s and verifier %s ", $token, $consumer, $verifier), __FILE__); $rt = new Token(); $rt->consumer_key = $consumer->key; $rt->tok = $token->key; $rt->type = 0; // request $app = Oauth_application::getByConsumerKey($consumer->key); assert(!empty($app)); if ($rt->find(true) && $rt->state == 1 && $rt->verifier == $verifier) { // authorized common_debug('Request token found.', __FILE__); // find the app and profile associated with this token $tokenAssoc = Oauth_token_association::staticGet('token', $rt->tok); if (!$tokenAssoc) { throw new Exception(_('Could not find a profile and application associated with the request token.')); } // check to see if we have previously issued an access token for this application // and profile $appUser = new Oauth_application_user(); $appUser->application_id = $app->id; $appUser->profile_id = $tokenAssoc->profile_id; $result = $appUser->find(true); if (!empty($result)) { common_log(LOG_INFO, sprintf("Existing access token found for application %s, profile %s.", $app->id, $tokenAssoc->profile_id)); $at = new Token(); // fetch the full access token $at->consumer_key = $consumer->key; $at->tok = $appUser->token; $result = $at->find(true); if (!$result) { throw new Exception(_('Could not issue access token.')); } // Yay, we can re-issue the access token return new OAuthToken($at->tok, $at->secret); } else { common_log(LOG_INFO, sprintf("Creating new access token for application %s, profile %s.", $app->id, $tokenAssoc->profile_id)); // make a brand new access token $at = new Token(); $at->consumer_key = $consumer->key; $at->tok = common_good_rand(16); $at->secret = common_good_rand(16); $at->type = 1; // access $at->verifier = $verifier; $at->verified_callback = $rt->verified_callback; // 1.0a $at->created = common_sql_now(); if (!$at->insert()) { $e = $at->_lastError; common_debug('access token "' . $at->tok . '" not inserted: "' . $e->message . '"', __FILE__); return null; } else { common_debug('access token "' . $at->tok . '" inserted', __FILE__); // burn the old one $orig_rt = clone $rt; $rt->state = 2; // used if (!$rt->update($orig_rt)) { return null; } common_debug('request token "' . $rt->tok . '" updated', __FILE__); } // insert a new Oauth_application_user record w/access token $appUser = new Oauth_application_user(); $appUser->profile_id = $tokenAssoc->profile_id; $appUser->application_id = $app->id; $appUser->access_type = $app->access_type; $appUser->token = $at->tok; $appUser->created = common_sql_now(); $result = $appUser->insert(); if (!$result) { common_log_db_error($appUser, 'INSERT', __FILE__); // TRANS: Server error displayed when a database error occurs. $this->serverError(_('Database error inserting OAuth application user.')); } // Okay, good return new OAuthToken($at->tok, $at->secret); } } else { // the token was not authorized or not verfied common_log(LOG_INFO, sprintf("API OAuth - Attempt to exchange unauthorized or unverified request token %s for an access token.", $rt->tok)); return null; } }
function handlePost() { // check session token for CSRF protection. $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { $this->showForm(_('There was a problem with your session token. Try again, please.')); return; } // check creds $user = null; if (!common_logged_in()) { // XXX Force credentials check? // @fixme this should probably use a unified login form handler $user = null; if (Event::handle('StartOAuthLoginCheck', array($this, &$user))) { $user = common_check_user($this->nickname, $this->password); } Event::handle('EndOAuthLoginCheck', array($this, &$user)); if (empty($user)) { // TRANS: Form validation error given when an invalid username and/or password was passed to the OAuth API. $this->showForm(_("Invalid nickname / password!")); return; } } else { $user = common_current_user(); } // fetch the token $this->reqToken = $this->store->getTokenByKey($this->oauthTokenParam); assert(!empty($this->reqToken)); if ($this->arg('allow')) { // mark the req token as authorized try { $this->store->authorize_token($this->oauthTokenParam); } catch (Exception $e) { $this->serverError($e->getMessage()); } common_log(LOG_INFO, sprintf("API OAuth - User %d (%s) has authorized request token %s for OAuth application %d (%s).", $user->id, $user->nickname, $this->reqToken->tok, $this->app->id, $this->app->name)); // XXX: Make sure we have a oauth_token_association table. The table // is now in the main schema, but because it is being added with // a point release, it's unlikely to be there. This code can be // removed as of 1.0. $this->ensureOauthTokenAssociationTable(); $tokenAssoc = new Oauth_token_association(); $tokenAssoc->profile_id = $user->id; $tokenAssoc->application_id = $this->app->id; $tokenAssoc->token = $this->oauthTokenParam; $tokenAssoc->created = common_sql_now(); $result = $tokenAssoc->insert(); if (!$result) { common_log_db_error($tokenAssoc, 'INSERT', __FILE__); // TRANS: Server error displayed when a database action fails. $this->serverError(_('Database error inserting oauth_token_association.')); } $callback = $this->getCallback(); if (!empty($callback) && $this->reqToken->verified_callback != 'oob') { $targetUrl = $this->buildCallbackUrl($callback, array('oauth_token' => $this->oauthTokenParam, 'oauth_verifier' => $this->reqToken->verifier)); common_log(LOG_INFO, "Redirecting to callback: {$targetUrl}"); // Redirect the user to the provided OAuth callback common_redirect($targetUrl, 303); } elseif ($this->app->type == 2) { // Strangely, a web application seems to want to do the OOB // workflow. Because no callback was specified anywhere. common_log(LOG_WARNING, sprintf("API OAuth - No callback provided for OAuth web client ID %s (%s) " . "during authorization step. Falling back to OOB workflow.", $this->app->id, $this->app->name)); } // Otherwise, inform the user that the rt was authorized $this->showAuthorized(); } else { if ($this->arg('cancel')) { common_log(LOG_INFO, sprintf("API OAuth - User %d (%s) refused to authorize request token %s for OAuth application %d (%s).", $user->id, $user->nickname, $this->reqToken->tok, $this->app->id, $this->app->name)); try { $this->store->revoke_token($this->oauthTokenParam, 0); } catch (Exception $e) { $this->ServerError($e->getMessage()); } $callback = $this->getCallback(); // If there's a callback available, inform the consumer the user // has refused authorization if (!empty($callback) && $this->reqToken->verified_callback != 'oob') { $targetUrl = $this->buildCallbackUrl($callback, array('oauth_problem' => 'user_refused')); common_log(LOG_INFO, "Redirecting to callback: {$targetUrl}"); // Redirect the user to the provided OAuth callback common_redirect($targetUrl, 303); } // otherwise inform the user that authorization for the rt was declined $this->showCanceled(); } else { // TRANS: Client error given on when invalid data was passed through a form in the OAuth API. $this->clientError(_('Unexpected form submission.')); } } }
$schema['profile_tag_subscription'] = array('fields' => array('profile_tag_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile_tag'), 'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified')), 'primary key' => array('profile_tag_id', 'profile_id'), 'foreign keys' => array('profile_tag_subscription_profile_list_id_fkey' => array('profile_list', array('profile_tag_id' => 'id')), 'profile_tag_subscription_profile_id_fkey' => array('profile', array('profile_id' => 'id'))), 'indexes' => array('profile_tag_subscription_profile_id_idx' => array('profile_id'), 'profile_tag_subscription_created_idx' => array('created'))); $schema['profile_block'] = array('fields' => array('blocker' => array('type' => 'int', 'not null' => true, 'description' => 'user making the block'), 'blocked' => array('type' => 'int', 'not null' => true, 'description' => 'profile that is blocked'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date of blocking')), 'foreign keys' => array('profile_block_blocker_fkey' => array('user', array('blocker' => 'id')), 'profile_block_blocked_fkey' => array('profile', array('blocked' => 'id'))), 'primary key' => array('blocker', 'blocked')); $schema['user_group'] = array('fields' => array('id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'), 'nickname' => array('type' => 'varchar', 'length' => 64, 'description' => 'nickname for addressing'), 'fullname' => array('type' => 'varchar', 'length' => 255, 'description' => 'display name'), 'homepage' => array('type' => 'varchar', 'length' => 255, 'description' => 'URL, cached so we dont regenerate'), 'description' => array('type' => 'text', 'description' => 'group description'), 'location' => array('type' => 'varchar', 'length' => 255, 'description' => 'related physical location, if any'), 'original_logo' => array('type' => 'varchar', 'length' => 255, 'description' => 'original size logo'), 'homepage_logo' => array('type' => 'varchar', 'length' => 255, 'description' => 'homepage (profile) size logo'), 'stream_logo' => array('type' => 'varchar', 'length' => 255, 'description' => 'stream-sized logo'), 'mini_logo' => array('type' => 'varchar', 'length' => 255, 'description' => 'mini logo'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'), 'uri' => array('type' => 'varchar', 'length' => 255, 'description' => 'universal identifier'), 'mainpage' => array('type' => 'varchar', 'length' => 255, 'description' => 'page for group info to link to'), 'join_policy' => array('type' => 'int', 'size' => 'tiny', 'description' => '0=open; 1=requires admin approval'), 'force_scope' => array('type' => 'int', 'size' => 'tiny', 'description' => '0=never,1=sometimes,-1=always')), 'primary key' => array('id'), 'unique keys' => array('user_group_uri_key' => array('uri')), 'indexes' => array('user_group_nickname_idx' => array('nickname'))); $schema['group_member'] = array('fields' => array('group_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to user_group'), 'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to profile table'), 'is_admin' => array('type' => 'int', 'size' => 'tiny', 'default' => 0, 'description' => 'is this user an admin?'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified')), 'primary key' => array('group_id', 'profile_id'), 'foreign keys' => array('group_member_group_id_fkey' => array('user_group', array('group_id' => 'id')), 'group_member_profile_id_fkey' => array('profile', array('profile_id' => 'id'))), 'indexes' => array('group_member_profile_id_idx' => array('profile_id'), 'group_member_created_idx' => array('created'))); $schema['related_group'] = array('fields' => array('group_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to user_group'), 'related_group_id' => array('type' => 'int', 'not null' => true, 'description' => 'foreign key to user_group'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created')), 'primary key' => array('group_id', 'related_group_id'), 'foreign keys' => array('related_group_group_id_fkey' => array('user_group', array('group_id' => 'id')), 'related_group_related_group_id_fkey' => array('user_group', array('related_group_id' => 'id')))); $schema['group_inbox'] = array('description' => 'Many-many table listing notices posted to a given group, or which groups a given notice was posted to.', 'fields' => array('group_id' => array('type' => 'int', 'not null' => true, 'description' => 'group receiving the message'), 'notice_id' => array('type' => 'int', 'not null' => true, 'description' => 'notice received'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date the notice was created')), 'primary key' => array('group_id', 'notice_id'), 'foreign keys' => array('group_inbox_group_id_fkey' => array('user_group', array('group_id' => 'id')), 'group_inbox_notice_id_fkey' => array('notice', array('notice_id' => 'id'))), 'indexes' => array('group_inbox_created_idx' => array('created'), 'group_inbox_notice_id_idx' => array('notice_id'))); $schema['file'] = array('fields' => array('id' => array('type' => 'serial', 'not null' => true), 'url' => array('type' => 'varchar', 'length' => 255, 'description' => 'destination URL after following redirections'), 'mimetype' => array('type' => 'varchar', 'length' => 50, 'description' => 'mime type of resource'), 'size' => array('type' => 'int', 'description' => 'size of resource when available'), 'title' => array('type' => 'varchar', 'length' => 255, 'description' => 'title of resource when available'), 'date' => array('type' => 'int', 'description' => 'date of resource according to http query'), 'protected' => array('type' => 'int', 'description' => 'true when URL is private (needs login)'), 'filename' => array('type' => 'varchar', 'length' => 255, 'description' => 'if a local file, name of the file'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified')), 'primary key' => array('id'), 'unique keys' => array('file_url_key' => array('url'))); $schema['file_oembed'] = array('fields' => array('file_id' => array('type' => 'int', 'not null' => true, 'description' => 'oEmbed for that URL/file'), 'version' => array('type' => 'varchar', 'length' => 20, 'description' => 'oEmbed spec. version'), 'type' => array('type' => 'varchar', 'length' => 20, 'description' => 'oEmbed type: photo, video, link, rich'), 'mimetype' => array('type' => 'varchar', 'length' => 50, 'description' => 'mime type of resource'), 'provider' => array('type' => 'varchar', 'length' => 50, 'description' => 'name of this oEmbed provider'), 'provider_url' => array('type' => 'varchar', 'length' => 255, 'description' => 'URL of this oEmbed provider'), 'width' => array('type' => 'int', 'description' => 'width of oEmbed resource when available'), 'height' => array('type' => 'int', 'description' => 'height of oEmbed resource when available'), 'html' => array('type' => 'text', 'description' => 'html representation of this oEmbed resource when applicable'), 'title' => array('type' => 'varchar', 'length' => 255, 'description' => 'title of oEmbed resource when available'), 'author_name' => array('type' => 'varchar', 'length' => 50, 'description' => 'author name for this oEmbed resource'), 'author_url' => array('type' => 'varchar', 'length' => 255, 'description' => 'author URL for this oEmbed resource'), 'url' => array('type' => 'varchar', 'length' => 255, 'description' => 'URL for this oEmbed resource when applicable (photo, link)'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified')), 'primary key' => array('file_id'), 'foreign keys' => array('file_oembed_file_id_fkey' => array('file', array('file_id' => 'id')))); $schema['file_redirection'] = array('fields' => array('url' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'short URL (or any other kind of redirect) for file (id)'), 'file_id' => array('type' => 'int', 'description' => 'short URL for what URL/file'), 'redirections' => array('type' => 'int', 'description' => 'redirect count'), 'httpcode' => array('type' => 'int', 'description' => 'HTTP status code (20x, 30x, etc.)'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified')), 'primary key' => array('url'), 'foreign keys' => array('file_redirection_file_id_fkey' => array('file' => array('file_id' => 'id')))); $schema['file_thumbnail'] = array('fields' => array('file_id' => array('type' => 'int', 'not null' => true, 'description' => 'thumbnail for what URL/file'), 'url' => array('type' => 'varchar', 'length' => 255, 'description' => 'URL of thumbnail'), 'width' => array('type' => 'int', 'description' => 'width of thumbnail'), 'height' => array('type' => 'int', 'description' => 'height of thumbnail'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified')), 'primary key' => array('file_id'), 'foreign keys' => array('file_thumbnail_file_id_fkey' => array('file', array('file_id' => 'id'))), 'unique keys' => array('file_thumbnail_url_key' => array('url'))); $schema['file_to_post'] = array('fields' => array('file_id' => array('type' => 'int', 'not null' => true, 'description' => 'id of URL/file'), 'post_id' => array('type' => 'int', 'not null' => true, 'description' => 'id of the notice it belongs to'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified')), 'primary key' => array('file_id', 'post_id'), 'foreign keys' => array('file_to_post_file_id_fkey' => array('file', array('file_id' => 'id')), 'file_to_post_post_id_fkey' => array('notice', array('post_id' => 'id'))), 'indexes' => array('post_id_idx' => array('post_id'))); $schema['group_block'] = array('fields' => array('group_id' => array('type' => 'int', 'not null' => true, 'description' => 'group profile is blocked from'), 'blocked' => array('type' => 'int', 'not null' => true, 'description' => 'profile that is blocked'), 'blocker' => array('type' => 'int', 'not null' => true, 'description' => 'user making the block'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date of blocking')), 'primary key' => array('group_id', 'blocked'), 'foreign keys' => array('group_block_group_id_fkey' => array('user_group', array('group_id' => 'id')), 'group_block_blocked_fkey' => array('profile', array('blocked' => 'id')), 'group_block_blocker_fkey' => array('user', array('blocker' => 'id')))); $schema['group_alias'] = array('fields' => array('alias' => array('type' => 'varchar', 'length' => 64, 'not null' => true, 'description' => 'additional nickname for the group'), 'group_id' => array('type' => 'int', 'not null' => true, 'description' => 'group profile is blocked from'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date alias was created')), 'primary key' => array('alias'), 'foreign keys' => array('group_alias_group_id_fkey' => array('user_group', array('group_id' => 'id'))), 'indexes' => array('group_alias_group_id_idx' => array('group_id'))); $schema['session'] = array('fields' => array('id' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'session ID'), 'session_data' => array('type' => 'text', 'description' => 'session data'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified')), 'primary key' => array('id'), 'indexes' => array('session_modified_idx' => array('modified'))); $schema['deleted_notice'] = array('fields' => array('id' => array('type' => 'int', 'not null' => true, 'description' => 'identity of notice'), 'profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'author of the notice'), 'uri' => array('type' => 'varchar', 'length' => 255, 'description' => 'universally unique identifier, usually a tag URI'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date the notice record was created'), 'deleted' => array('type' => 'datetime', 'not null' => true, 'description' => 'date the notice record was created')), 'primary key' => array('id'), 'unique keys' => array('deleted_notice_uri_key' => array('uri')), 'indexes' => array('deleted_notice_profile_id_idx' => array('profile_id'))); $schema['config'] = array('fields' => array('section' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'default' => '', 'description' => 'configuration section'), 'setting' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'default' => '', 'description' => 'configuration setting'), 'value' => array('type' => 'varchar', 'length' => 255, 'description' => 'configuration value')), 'primary key' => array('section', 'setting')); $schema['profile_role'] = array('fields' => array('profile_id' => array('type' => 'int', 'not null' => true, 'description' => 'account having the role'), 'role' => array('type' => 'varchar', 'length' => 32, 'not null' => true, 'description' => 'string representing the role'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date the role was granted')), 'primary key' => array('profile_id', 'role'), 'foreign keys' => array('profile_role_profile_id_fkey' => array('profile', array('profile_id' => 'id')))); $schema['location_namespace'] = array('fields' => array('id' => array('type' => 'int', 'not null' => true, 'description' => 'identity for this namespace'), 'description' => array('type' => 'varchar', 'length' => 255, 'description' => 'description of the namespace'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date the record was created'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified')), 'primary key' => array('id')); $schema['login_token'] = array('fields' => array('user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user owning this token'), 'token' => array('type' => 'char', 'length' => 32, 'not null' => true, 'description' => 'token useable for logging in'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified')), 'primary key' => array('user_id'), 'foreign keys' => array('login_token_user_id_fkey' => array('user', array('user_id' => 'id')))); $schema['user_location_prefs'] = array('fields' => array('user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user who has the preference'), 'share_location' => array('type' => 'int', 'size' => 'tiny', 'default' => 1, 'description' => 'Whether to share location data'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified')), 'primary key' => array('user_id'), 'foreign keys' => array('user_location_prefs_user_id_fkey' => array('user', array('user_id' => 'id')))); $schema['inbox'] = array('fields' => array('user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user receiving the notice'), 'notice_ids' => array('type' => 'blob', 'description' => 'packed list of notice ids')), 'primary key' => array('user_id'), 'foreign keys' => array('inbox_user_id_fkey' => array('user', array('user_id' => 'id')))); // @fixme possibly swap this for a more general prefs table? $schema['user_im_prefs'] = array('fields' => array('user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user'), 'screenname' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'screenname on this service'), 'transport' => array('type' => 'varchar', 'length' => 255, 'not null' => true, 'description' => 'transport (ex xmpp, aim)'), 'notify' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Notify when a new notice is sent'), 'replies' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Send replies from people not subscribed to'), 'microid' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 1, 'description' => 'Publish a MicroID'), 'updatefrompresence' => array('type' => 'int', 'size' => 'tiny', 'not null' => true, 'default' => 0, 'description' => 'Send replies from people not subscribed to.'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified')), 'primary key' => array('user_id', 'transport'), 'unique keys' => array('transport_screenname_key' => array('transport', 'screenname')), 'foreign keys' => array('user_im_prefs_user_id_fkey' => array('user', array('user_id' => 'id')))); $schema['conversation'] = array('fields' => array('id' => array('type' => 'serial', 'not null' => true, 'description' => 'unique identifier'), 'uri' => array('type' => 'varchar', 'length' => 225, 'description' => 'URI of the conversation'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified')), 'primary key' => array('id'), 'unique keys' => array('conversation_uri_key' => array('uri'))); $schema['local_group'] = array('description' => 'Record for a user group on the local site, with some additional info not in user_group', 'fields' => array('group_id' => array('type' => 'int', 'not null' => true, 'description' => 'group represented'), 'nickname' => array('type' => 'varchar', 'length' => 64, 'description' => 'group represented'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified')), 'primary key' => array('group_id'), 'foreign keys' => array('local_group_group_id_fkey' => array('user_group', array('group_id' => 'id'))), 'unique keys' => array('local_group_nickname_key' => array('nickname'))); $schema['user_urlshortener_prefs'] = array('fields' => array('user_id' => array('type' => 'int', 'not null' => true, 'description' => 'user'), 'urlshorteningservice' => array('type' => 'varchar', 'length' => 50, 'default' => 'internal', 'description' => 'service to use for auto-shortening URLs'), 'maxurllength' => array('type' => 'int', 'not null' => true, 'description' => 'urls greater than this length will be shortened, 0 = always, null = never'), 'maxnoticelength' => array('type' => 'int', 'not null' => true, 'description' => 'notices with content greater than this value will have all urls shortened, 0 = always, null = never'), 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified')), 'primary key' => array('user_id'), 'foreign keys' => array('user_urlshortener_prefs_user_id_fkey' => array('user', array('user_id' => 'id')))); $schema['schema_version'] = array('description' => 'To avoid checking database structure all the time, we store a checksum of the expected schema info for each table here. If it has not changed since the last time we checked the table, we can leave it as is.', 'fields' => array('table_name' => array('type' => 'varchar', 'length' => '64', 'not null' => true, 'description' => 'Table name'), 'checksum' => array('type' => 'varchar', 'length' => '64', 'not null' => true, 'description' => 'Checksum of schema array; a mismatch indicates we should check the table more thoroughly.'), 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified')), 'primary key' => array('table_name')); $schema['group_join_queue'] = Group_join_queue::schemaDef(); $schema['subscription_queue'] = Subscription_queue::schemaDef(); $schema['oauth_token_association'] = Oauth_token_association::schemaDef();