#!/usr/bin/python
#
# @package      hubzero-filexfer-xlate
# @file         filexfer-xlate
# @author       Rick Kennell <kennell@purdue.edu>
# @author       Pascal Meunier <pmeunier@purdue.edu>
# @copyright    Copyright (c) 2005-2013 HUBzero Foundation, LLC.
# @license      http://www.gnu.org/licenses/lgpl-3.0.html LGPLv3
#
# Copyright (c) 2005-2013 HUBzero Foundation, LLC.
#
# This file is part of: The HUBzero(R) Platform for Scientific Collaboration
#
# The HUBzero(R) Platform for Scientific Collaboration (HUBzero) is free
# software: you can redistribute it and/or modify it under the terms of
# the GNU Lesser General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any
# later version.
#
# HUBzero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# HUBzero is a registered trademark of HUBzero Foundation, LLC.

""" URL translation service for Apache.
Deployment: master host (web server)
This file is called based on settings in the following files in /etc/apache2:

sites-available/hub-ssl:	RewriteMap	xlate		prg:/usr/bin/filexfer-xlate
sites-available/hub-ssl:		RewriteRule	^filexfer/(.*)		${xlate:$1|nothing} [P,QSA,L]
sites-enabled/hub-ssl:	RewriteMap	xlate		prg:/usr/bin/filexfer-xlate
sites-enabled/hub-ssl:		RewriteRule	^filexfer/(.*)		${xlate:$1|nothing} [P,QSA,L]

Last modified by Pascal Meunier June 7 2010:
removed SQL injection, used mw_common, tidied up, entered comments

"""

import sys
import os
import MySQLdb
import re
import time

ALPHANUM_REGEXP = r'\A[a-zA-Z0-9]+\Z'
VERBOSE = False
logfile_name = "/var/log/filexfer-xlate/filexfer-xlate.log"

if os.path.exists("/etc/mw-client/mw-client.conf"):
  config_file="/etc/mw-client/mw-client.conf"
elif os.path.exists("/etc/mw-www/maxwell.conf"):
  config_file="/etc/mw-www/maxwell.conf"
elif os.path.exists("/etc/hubzero/maxwell.conf"):
  config_file="/etc/hubzero/maxwell.conf"
elif os.path.exists("/etc/mw/maxwell.conf"):
  config_file="/etc/mw/maxwell.conf"
else:
  config_file=""

# configuration variables
mysql_host = None
mysql_user = None
mysql_password = None
mysql_db = None

#=============================================================================
# Load the configuration and override the variables above.
#=============================================================================
try:
  execfile(config_file)
except IOError:
  print "The configuration file '%s' is not readable" % (config_file)
  sys.exit(1)

#=============================================================================
# Set up errors to go to the log file.
#=============================================================================
def openlog(filename):
  if not os.isatty(2):
    try:
      log = open(filename,"a+")
      os.dup2(log.fileno(), sys.stderr.fileno())
      log.close()
    except:
      pass

#=============================================================================
# Log a message.
#=============================================================================
def log(msg):
  timestamp = time.strftime("%m/%d %H:%M:%S")
  msg = "[%s]%d: %s\n" % (timestamp, os.getpid(), msg)
  if (os.isatty(2)):
    print msg
  else:
    sys.stderr.write(msg + "\n")

#=============================================================================
# Create database connection.
#=============================================================================
def db_connect():
  try:
    db = MySQLdb.connect(host=mysql_host, user=mysql_user, passwd=mysql_password, db=mysql_db)
    return db
  except:
    log("Exception in db_connect")

#=============================================================================
# MySQL helpers
#=============================================================================
def mysql(c,cmd):
  try:
    count = c.execute(cmd)
    return c.fetchall()
  except MySQLdb.MySQLError, (num, expl):
    log("%s.  SQL was: %s" % (expl,cmd))
    return ()
  except:
    log("Some other MySQL exception.")
    return ()

def mysql_act(c,cmd):
  try:
    count = c.execute(cmd)
    return ""
  except MySQLdb.MySQLError, (num, expl):
    return expl

#=============================================================================
# Main program
#=============================================================================

openlog(logfile_name)
log("Starting up.")

while 1:
  try:
    line = sys.stdin.readline()
    if line == "":
      log("No input")
      break

    line = line.strip()
    i = line.find("/")
    cookie = line[0:i]
    uri = line[i:]
    m = re.match(ALPHANUM_REGEXP, cookie)
    if m is None:
      raise StandardError("Bad cookie '%s'" % cookie)

    db = db_connect()
    c = db.cursor()

    arr = mysql(c,"""SELECT fileperm.sessnum,fileuser,hostname,dispnum
                     FROM fileperm join display
                     ON fileperm.sessnum = display.sessnum
                     WHERE fileperm.cookie='%s'""" % cookie)
    db.close()

    trans = "NULL"

    if len(arr) != 1:
      log("No database entry found for ID %s." % cookie)
    else:
      sess = arr[0][0]
      user = arr[0][1]
      host = arr[0][2]
      disp = arr[0][3]
      port = disp + 9000
      trans = "http://" + host + ":" + str(port) + uri
      log("Translation is %s" % trans)

    sys.stdout.write(trans + "\n")
    sys.stdout.flush()
    if VERBOSE:
       log("Done")

  except:
    log("Exception: " + str(sys.exc_info()[0]))
    sys.stdout.write("\n")
    sys.stdout.flush()

log("Exiting while loop???")

# If the while loop finishes for some reason...
sys.exit(0)
