hydrus/include/HydrusSessions.py

340 lines
12 KiB
Python
Raw Normal View History

2013-03-15 02:38:12 +00:00
import collections
2013-11-27 18:27:11 +00:00
import hashlib
2013-03-15 02:38:12 +00:00
import httplib
import HydrusConstants as HC
2013-07-24 20:26:00 +00:00
import HydrusExceptions
2013-03-15 02:38:12 +00:00
import os
import Queue
import re
import sqlite3
import sys
import threading
import time
import traceback
import wx
import yaml
2013-10-02 22:06:06 +00:00
HYDRUS_SESSION_EXPIRY_TIME = 30 * 86400
2013-11-27 18:27:11 +00:00
class HydrusMessagingSessionManagerServer():
def __init__( self ):
existing_sessions = HC.app.Read( 'messaging_sessions' )
self._sessions = collections.defaultdict( dict )
for ( service_identifier, session_tuples ) in existing_sessions:
self._sessions[ service_identifier ] = { session_key : ( account, identifier, name, expiry ) for ( session_Key, account, identifier, name, expiry ) in session_tuples }
def GetIdentityAndName( self, service_identifier, session_key ):
if session_key not in self._sessions[ service_identifier ]: raise HydrusExceptions.SessionException( 'Did not find that session!' )
else:
( account, identity, name, expiry ) = self._sessions[ service_identifier ][ session_key ]
now = HC.GetNow()
if now > expiry:
del self._sessions[ service_identifier ][ session_key ]
raise HydrusExceptions.SessionException( 'Session expired!' )
return ( identity, name )
def AddSession( self, service_identifier, access_key, name ):
session_key = os.urandom( 32 )
account_identifier = HC.AccountIdentifier( access_key = access_key )
account = HC.app.Read( 'account', service_identifier, account_identifier )
account_identifier = account.GetAccountIdentifier() # for better account_id based identifier
identity = hashlib.sha256( access_key ).digest()
now = HC.GetNow()
expiry = now + HYDRUS_SESSION_EXPIRY_TIME
self._sessions[ service_identifier ][ session_key ] = ( account, identity, name, expiry )
HC.app.Write( 'messaging_session', service_identifier, session_key, account, identity, name, expiry )
return session_key
2013-03-15 02:38:12 +00:00
class HydrusSessionManagerClient():
def __init__( self ):
2013-07-10 20:25:57 +00:00
existing_sessions = HC.app.Read( 'hydrus_sessions' )
2013-03-15 02:38:12 +00:00
self._sessions = { service_identifier : ( session_key, expiry ) for ( service_identifier, session_key, expiry ) in existing_sessions }
self._lock = threading.Lock()
def DeleteSessionKey( self, service_identifier ):
with self._lock:
2013-07-10 20:25:57 +00:00
HC.app.Write( 'delete_hydrus_session_key', service_identifier )
2013-03-15 02:38:12 +00:00
del self._sessions[ service_identifier ]
def GetSessionKey( self, service_identifier ):
2013-07-31 21:26:38 +00:00
now = HC.GetNow()
2013-03-15 02:38:12 +00:00
with self._lock:
if service_identifier in self._sessions:
( session_key, expiry ) = self._sessions[ service_identifier ]
if now + 600 > expiry: del self._sessions[ service_identifier ]
else: return session_key
# session key expired or not found
2013-07-10 20:25:57 +00:00
service = HC.app.Read( 'service', service_identifier )
2013-03-15 02:38:12 +00:00
connection = service.GetConnection()
connection.Get( 'session_key' )
cookies = connection.GetCookies()
try: session_key = cookies[ 'session_key' ].decode( 'hex' )
except: raise Exception( 'Service did not return a session key!' )
2013-10-02 22:06:06 +00:00
expiry = now + HYDRUS_SESSION_EXPIRY_TIME
2013-03-15 02:38:12 +00:00
self._sessions[ service_identifier ] = ( session_key, expiry )
2013-07-10 20:25:57 +00:00
HC.app.Write( 'hydrus_session', service_identifier, session_key, expiry )
2013-03-15 02:38:12 +00:00
return session_key
class HydrusSessionManagerServer():
def __init__( self ):
2013-10-02 22:06:06 +00:00
existing_sessions = HC.app.Read( 'sessions' )
2013-03-15 02:38:12 +00:00
2013-11-06 18:22:07 +00:00
self._account_ids_to_session_keys = collections.defaultdict( HC.default_dict_set )
2013-10-30 22:28:06 +00:00
2013-11-06 18:22:07 +00:00
self._account_cache = collections.defaultdict( dict )
self._sessions = collections.defaultdict( dict )
for ( session_key, service_identifier, account, expiry ) in existing_sessions:
self._sessions[ service_identifier ][ session_key ] = ( account, expiry )
account_id = account.GetAccountId()
self._account_ids_to_session_keys[ service_identifier ][ account_id ].add( session_key )
2013-03-15 02:38:12 +00:00
self._lock = threading.Lock()
2013-11-06 18:22:07 +00:00
HC.pubsub.sub( self, 'RefreshAllAccounts', 'update_all_session_accounts' )
2013-03-15 02:38:12 +00:00
2013-10-30 22:28:06 +00:00
def AddSession( self, service_identifier, account_identifier ):
2013-11-06 18:22:07 +00:00
with self._lock:
if account_identifier not in self._account_cache[ service_identifier ]:
account = HC.app.Read( 'account', service_identifier, account_identifier )
account_identifier = account.GetAccountIdentifier() # get the account_id based account_identifier
if account_identifier not in self._account_cache[ service_identifier ]:
self._account_cache[ service_identifier ][ account_identifier ] = account
account = self._account_cache[ service_identifier ][ account_identifier ]
2013-10-30 22:28:06 +00:00
2013-11-06 18:22:07 +00:00
account_id = account.GetAccountId()
2013-10-30 22:28:06 +00:00
2013-11-06 18:22:07 +00:00
session_key = os.urandom( 32 )
2013-10-30 22:28:06 +00:00
2013-11-06 18:22:07 +00:00
self._account_ids_to_session_keys[ service_identifier ][ account_id ].add( session_key )
now = HC.GetNow()
expiry = now + HYDRUS_SESSION_EXPIRY_TIME
HC.app.Write( 'session', session_key, service_identifier, account, expiry )
2013-10-30 22:28:06 +00:00
2013-11-06 18:22:07 +00:00
self._sessions[ service_identifier ][ session_key ] = ( account, expiry )
2013-10-02 22:06:06 +00:00
2013-11-06 18:22:07 +00:00
return ( session_key, expiry )
2013-10-02 22:06:06 +00:00
2013-11-06 18:22:07 +00:00
def GetAccount( self, session_key, service_identifier ):
2013-03-15 02:38:12 +00:00
2013-11-06 18:22:07 +00:00
now = HC.GetNow()
2013-03-15 02:38:12 +00:00
2013-10-02 22:06:06 +00:00
with self._lock:
2013-11-06 18:22:07 +00:00
if session_key in self._sessions[ service_identifier ]:
( account, expiry ) = self._sessions[ service_identifier ][ session_key ]
if now > expiry: del self._sessions[ service_identifier ][ session_key ]
else: return account
raise HydrusExceptions.SessionException()
2013-10-02 22:06:06 +00:00
2013-11-06 18:22:07 +00:00
def RefreshAccounts( self, service_identifier, account_identifiers ):
with self._lock:
for account_identifier in account_identifiers:
account = HC.app.Read( 'account', service_identifier, account_identifier )
account_identifier = account.GetAccountIdentifier() # get the account_id based account_identifier
self._account_cache[ service_identifier ][ account_identifier ] = account
account_id = account.GetAccountId()
if account_id in self._account_ids_to_session_keys[ service_identifier ]:
session_keys = self._account_ids_to_session_keys[ service_identifier ][ account_id ]
for session_key in session_keys:
( old_account, expiry ) = self._sessions[ service_identifier ][ session_key ]
self._sessions[ service_identifier ][ session_key ] = ( account, expiry )
2013-03-15 02:38:12 +00:00
2013-11-06 18:22:07 +00:00
def RefreshAllAccounts( self ):
existing_sessions = HC.app.Read( 'sessions' )
self._account_ids_to_session_keys = collections.defaultdict( HC.default_dict_set )
self._account_cache = collections.defaultdict( dict )
self._sessions = collections.defaultdict( dict )
for ( session_key, service_identifier, account, expiry ) in existing_sessions:
self._sessions[ service_identifier ][ session_key ] = ( account, expiry )
account_id = account.GetAccountId()
self._account_ids_to_session_keys[ service_identifier ][ account_id ].add( session_key )
class WebSessionManagerClient():
def __init__( self ):
existing_sessions = HC.app.Read( 'web_sessions' )
self._sessions = { name : ( cookies, expiry ) for ( name, cookies, expiry ) in existing_sessions }
self._lock = threading.Lock()
def GetCookies( self, name ):
2013-03-15 02:38:12 +00:00
2013-07-31 21:26:38 +00:00
now = HC.GetNow()
2013-03-15 02:38:12 +00:00
with self._lock:
2013-11-06 18:22:07 +00:00
if name in self._sessions:
2013-03-15 02:38:12 +00:00
2013-11-06 18:22:07 +00:00
( cookies, expiry ) = self._sessions[ name ]
2013-03-15 02:38:12 +00:00
2013-11-06 18:22:07 +00:00
if now + 300 > expiry: del self._sessions[ name ]
else: return cookies
2013-03-15 02:38:12 +00:00
2013-11-06 18:22:07 +00:00
# name not found, or expired
if name == 'hentai foundry':
connection = HC.get_connection( url = 'http://www.hentai-foundry.com', accept_cookies = True )
# this establishes the php session cookie, the csrf cookie, and tells hf that we are 18 years of age
connection.request( 'GET', '/?enterAgree=1' )
cookies = connection.GetCookies()
expiry = now + 60 * 60
elif name == 'pixiv':
( id, password ) = HC.app.Read( 'pixiv_account' )
if id == '' and password == '':
raise Exception( 'You need to set up your pixiv credentials in services->manage pixiv account.' )
connection = HC.get_connection( url = 'http://www.pixiv.net', accept_cookies = True )
form_fields = {}
form_fields[ 'mode' ] = 'login'
form_fields[ 'pixiv_id' ] = id
form_fields[ 'pass' ] = password
form_fields[ 'skip' ] = '1'
body = urllib.urlencode( form_fields )
headers = {}
headers[ 'Content-Type' ] = 'application/x-www-form-urlencoded'
# this logs in and establishes the php session cookie
response = connection.request( 'POST', '/login.php', headers = headers, body = body, follow_redirects = False )
cookies = connection.GetCookies()
# _ only given to logged in php sessions
if 'PHPSESSID' not in cookies or '_' not in cookies[ 'PHPSESSID' ]: raise Exception( 'Login credentials not accepted!' )
expiry = now + 30 * 86400
self._sessions[ name ] = ( cookies, expiry )
HC.app.Write( 'web_session', name, cookies, expiry )
return cookies
2013-03-15 02:38:12 +00:00