common.services.https package

Submodules

common.services.https.HtmlLogin module

2. Login service sessions

In this mode the Login service stores the usernames and passwords and gives out tokens. The storage of the usernames, passwords and tokens is called a Session.

3. Username and Password encryption

The username and password are encrypted with an AES key and stored in a cookie. This mode is there for historical reasons and should not be used any more.

class common.services.https.HtmlLogin.HtmlLogin(args)

Bases: common.services.https.HtmlLogin.HtmlLoginBase

This class generates a html page for logging in the database. When a user enters his username/password this tested against the database and stored as cookie on the client machine.

The following arguments can be given to this service :

change_pw If set show the change password link change_pw_url The url to change the password (default is /Password) cookie_lifetime The lifetime of the cookie (in days) cookie_username Username to show in the login field create_account_url The url to create a new account db_action The action; login, logout db_name The database name/url domain Domain to set the cookie on nextpage Define which page to go to after the action password The password to connect with prefix The prefix to show for the username input remember Include to store a cookie client side sso_application The application that requires login (url) target_server The server name to set the login cookie for, cookie name will contain the server name username The username to connect with

The default used template file is Login.html.tmpl, override in template_name

CLOSEWIN_REFRESH = '\n<html>\n<head>\n<script type="text/javascript">\nfunction refreshAndClose() {\n /* Below is not possible if parent and child are not same origin,\n * parent is responsible for reloading self.\n */\n /*window.opener.location.reload();*/\n window.close();\n}\n</script>\n</head>\n<body onload="refreshAndClose()">\n<p>This window should close itself ... if not please close manually ... </p>\n</body></html>\n'
FORWARD = '\n<html><head>\n<title>Forward</title>\n<meta http-equiv="refresh" content="0;URL=%(forward_url)s">\n</head>\n<body>\n<p>You are being forwarded to <a href="%(forward_url)s">%(forward_url)s</a></p>\n</body></html>\n'
URL_NAME = 'Login'
classmethod encryptUsernamePassword(username, password, key=None)

encrypt the username and password

getBottomMessage()

Return message (html) to be shown on the bottom

getCookies()

construct cookie(s) from the send username and password either login or logout

getExtraHead()

Derived classes can insert extra <head> statements with this method

getHtml()

generate html

getLoginCookieName()

return the prefered login cookie name

getOtherTabs()

Return the other tabs for login, main tab is database account login return a list of dictionaries, with each dictionary {

‘ID’:<identifier>, ‘HEAD’:<heading of the tab>, ‘BODY’:<body of the tab>,}
getTabsInit()

return the initialize statement for the tabs

classmethod get_url(change_pw=1, change_pw_url='', cookie_lifetime=0, create_account_url='', db_name='db.astro.rug.astro-wise.org', domain='', login_popup=False, nextpage='', prefix=None, server='awlogin.astro-wise.org', sso_application='', target_server='', use_sessions='')

return url for the login web service

handleOtherTabs(tmpl)

Handle the generation of the other tabs

initTemplate()

intialize the template

classmethod isLoginCookie(cookie_name)

return if cookie_name is a login cookie

loginCookieNames(all_names=False)

Return the possible login cookie names, the last entry should be the default. If all_names is given return all cookie names.

makeCookie(cookie_name, cookie_value, expires, domain)

make the cookie

ssoEnabled()

Are SSO tokens or tickets enabled in the database ?

classmethod ssoEnabled_cls()

classmethod version ssoEnabled

template_name = 'Login.html.tmpl'
testLogin()

try to login

classmethod useCookie(cookie_value, name='', key=None)

Try to determine username and password from encrypted cookie

do not use use log here, username and password are needed to initialize profiles which are needed for the logging

class common.services.https.HtmlLogin.HtmlLoginBase(args, package_file, parent=None)

Bases: common.services.general.HtmlBase.HtmlBase

Base class for the Login and Password change classes

classmethod get_encryption_key()

return the decoded encryption string from the environment

username_prefix = 'AW'
classmethod webLogin(dbname, username, password)

try to login to the database return error message in case of error

exception common.services.https.HtmlLogin.HtmlLoginError

Bases: Exception

common.services.https.HtmlPassword module

File HtmlPassword.py Author WJ Vriend (wjvriend @ astro.rug.nl)

class common.services.https.HtmlPassword.HtmlPassword(args)

Bases: common.services.https.HtmlLogin.HtmlLoginBase

This class generates a html page for changing the password of the user in the database.

template file - Password.html.tmpl

CLOSEWIN_RELOGIN = '\n<html>\n<head>\n<title>Status</title>\n</head>\n<body>\n<p>Your password has been changed in the database : %s</p>\n<p>Please close this window and (re)login.</p>\n</body></html>\n'
changePassword()

change the password of the user in the database, the following is checked: (1) the username should be a valid schema name (2) it shuold be possible to quote the password

getBottomMessage()

Return message (html) to be shown on the bottom

getCookies()

Remove the cookie with the old password when the password change was succesfull

getExtraHead()

Derived classes can insert extra <head> statements with this method

getHtml()

generate html

illegal_chars = ('"', ' ', '@')
illegal_chars_text = 'double quote, space or @'
makeCookie(cookie_value, expires, domain)

make the cookie

exception common.services.https.HtmlPassword.HtmlPasswordError

Bases: Exception

Will be raised when there is a problem changing the password

common.services.https.HttpsServer module

!!!! THIS MODULE IS OBSOLETE !!!!

The Https Web Server

* M2Crypto *

Note that when M2Crypto is installed it will be automatically used, and fasten the servive a lot

The current version of M2Crypto is not fully compatible with python 2.7, we made a patched version (see install)

In the future we will use the ssl module of python

* Certificates *

This service requires a private key and certificate, these are the steps to create them :

openssl genrsa -des3 -out server.key 1024 openssl req -new -key server.key -out server.csr openssl rsa -in server.key -out server.key openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

server.crt is the certificate, server.key is the private key see $AWEPIPE/common/services/genereal/HttpServer.cfg for an example of the configuration file under the [ssl] section the key and certificate must be specified

* Keys *

The login service uses the following keys (in Env):
encryption_key; to encrpyt and decrypt the username/passwords login_server_key_init; to allow other services to initiate a Session login_server_key_request; to allow other services to request a Session

Example how to generate random base64 encoded keys # python code import uuid u = uuid.uuid4() u.bytes.encode(“base64”)

Example running the service :

awe $AWEPIPE/common/services/https/HttpsServer.py -c <config_file>

common.services.https.HttpsServer.main(arguments)

the main method

common.services.https.HttpsServer.my_print(text)
common.services.https.HttpsServer.read_from_current_dir(filename, mode='r')

read file from the current dir

common.services.https.SSO module

SSO implementation classes, used for

  1. determining login and logout links of various SSO systems
class common.services.https.SSO.SSO

Bases: object

base class for all SSO implementations

return the Login link

return the Logout link

exception common.services.https.SSO.SSOError

Bases: Exception

class common.services.https.SSO.SSOFactory

Bases: object

SSO Factory class, returning the SSO class as defined in the Environment

classmethod get()

return the SSO class

class common.services.https.SSO.SSO_CAS

Bases: common.services.https.SSO.SSO

The CAS SSO

return the Login link

return the Login link

common.services.https.Sessions module

The Sessions class (dictionary) holds usernames and passwords, and relates these to sessions ids.

class common.services.https.Sessions.Sessions

Bases: dict

Class for handling sessions, a session is identified by a key and holds the username and password of an user

appendLogFile(lines)

append lines to log file with filename

clean()

do clean up, remove obsolete entries from dict

default_valid_time = 30
dump(use_lock=True)

dump the contents file

extend_valid_time_after_use = True
classmethod generateKey()

generate an unique key

getSession(session_id)

Return the Session with session_id

initSession(username, password, ip, max_count_accessed=-1, valid_untill=None, reuse=True)

add a session with credentials or reuse an existing session if reuse=True and username exists

classmethod load(filename)

load all sessions from file

removeSession(session_id)

remove the session with session_id

save(use_lock=True)

save all sessions to filename

saveAndDump(use_lock=True)

save the sessions as pickle and dump to log

sessionValid(session_id, check_disabled=True)

check if session with key is valid

session_attributes = ['username', 'password', 'started', 'last_accessed', 'count_accessed', 'max_count_accessed', 'valid_untill', 'disabled', 'ip_address']
sessions_dump = 'Sessions'
sessions_log = 'Sessions.log'
sessions_pickle = 'Sessions.pickle'
touchSession(session_id)

Touch the Session with session id, raise the count and set last accessed. Locking must be done by caller !

exception common.services.https.Sessions.SessionsError

Bases: Exception

common.services.https.ThreadedHTTPSServer module

This is the base class for HTTPS servers, both forked and threaded are defined.

class common.services.https.ThreadedHTTPSServer.CertificateMixin

Bases: object

Class handling certificates

get_socket(certificate, key, ciphers)

make and return the SSL socket based on https://markusholtermann.eu/2016/09/ssl-all-the-things-in-python/

get_socket_depricated(certificate, key, ciphers)

make and return the SSL socket, depricated, see python ssl docs on ssl.wrap_socket TODO remove or enable in specific cases ?

init_with_certificate(certificate, key, ciphers='', timeout=0)

initialize the certificates, set socket

class common.services.https.ThreadedHTTPSServer.ForkingHTTPsServer(server_address, RequestHandlerClass, bind_and_activate=True)

Bases: common.services.general.ThreadedHTTPServer.ForkingHTTPServer, common.services.https.ThreadedHTTPSServer.CertificateMixin

Forking HTTPs Server

common.services.https.ThreadedHTTPSServer.MyHttpsServer

alias of common.services.https.ThreadedHTTPSServer.ThreadingHTTPsServer

class common.services.https.ThreadedHTTPSServer.SSLSocketTimeout(sock=None, keyfile=None, certfile=None, server_side=False, cert_reqs=0, ssl_version=<_SSLMethod.PROTOCOL_SSLv23: 2>, ca_certs=None, do_handshake_on_connect=True, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, proto=0, fileno=None, suppress_ragged_eofs=True, npn_protocols=None, ciphers=None, server_hostname=None, _context=None)

Bases: ssl.SSLSocket

use a timed handshake method

do_handshake(*args, **kwargs)

Perform a TLS/SSL handshake.

exception common.services.https.ThreadedHTTPSServer.SSLSocketTimeoutError

Bases: Exception

class common.services.https.ThreadedHTTPSServer.ThreadingHTTPsServer(server_address, RequestHandlerClass, bind_and_activate=True)

Bases: common.services.general.ThreadedHTTPServer.ThreadingHTTPServer, common.services.https.ThreadedHTTPSServer.CertificateMixin

Threading HTTPs Server

common.services.https.XmlSession module

XmlSession is the interface between the login server and other services or clients

The requesting service authorizes itself with :

login_server_key_init to initiate a session login_server_key_request to request the information of a session

these should be defined in the Environment.cfg and can be generated with:

import uuid key = uuid.uuid4().hex

Usage examples :

# WISE services using sessions # first initialize a session on the login server, and get the session id # provide username, password and the <key>, this is one of the keys # defined on the server side in Env[‘login_server_key_init’] from common.services.https.XmlSession import XmlSession session_id = XmlSession.initSessionCurrentUser(server_key=<key>) # above uses Env for username/password, or specify explicit: session_id = XmlSession.initSession(<username>, <password>, server_key=<key>) # store session id in html, in cookie, or … # and use later to get the session with username, password and request key session = XmlSession.getSession(session_id, server_key=<key>) # Or use session_id in HTTP call to web service : # http://my.web.service/loginsession=<session_id>

# Non-WISE client (XmlSession can not be imported) # client code wants to open url’s on WISE services on account of a specific user # -> first get session from login service, use session to authenticate user from urllib.request import urlopen from urllib.parse import quote from StringIO import StringIO from xml.etree.ElementTree import ElementTree username = ‘…’ password = ‘…’ login_server_key_init = ‘…’ login_url = ‘https://awlogin.astro-wise.org/Session?request_session=default&login_server_key=%s&username=%s&password=%s’ % (login_server_key_init, username, password) xml = urlopen(login_url).read() element = ElementTree().parse(StringIO(xml)) session_id = element.text # now use the session_id to communicate with a WISE service, example : # url = ‘http://lofar.astro-wise.org/Lofar?mode=urls&observation_id=%s&project=%s&loginsession=%s’ % (obs_id, project, quote(session_id))

class common.services.https.XmlSession.XmlSession(args)

Bases: common.services.general.HtmlBase.HtmlBase

class for returning username and password from a session in xml using the http server interface

classmethod XmlAttribute(attribute, value)

return value escaped xml attribute

allowed_keys_init = ['']
allowed_keys_request = ['']
classmethod decode(xml)
decode the xml and
return session info (with username and password) return session id

in case of an error raise Exception

classmethod getContentType()

(overriden) return the http content-type header

getHtml()

There are four modes : 1. request_session; input username/password, output session_id 2. session_id; input session_id, output username/password

these two modes are normally used between a web server (dbview) and the login server
  1. init_session; request the init of a specific session, for example samp this mode is used between a client and a web server (dbview)
  2. remove_session; removes a session with the id given by remove_session
classmethod getSession(session_key, server_key='')

use the session key to get the session dict from server

get_init_session_args()

get arguments for the initSession call, depending on self.request_session

classmethod get_url(login_server_key, session_id)

return the url to use this service; init session

classmethod get_url_request(login_server_key, username, password, session='default', use_in_html=False)

return the url to use this service; request session info

classmethod initSession(username, password, server_key='', session='default', test_mode=False)

initialize a session with username and password

classmethod initSessionCurrentUser(server_key='', session='default')

initialize a session for the current user

classmethod initSession_samp(test_mode=False)

init a session for samp

xml_heading = '<?xml version="1.0" encoding="UTF-8"?>'
exception common.services.https.XmlSession.XmlSessionError

Bases: Exception

Module contents