Changeset 7115


Ignore:
Timestamp:
28/06/10 14:56:30 (9 years ago)
Author:
astephen
Message:

more work on admin interface etc.

Location:
cows_wps/trunk/cows_wps
Files:
1 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • cows_wps/trunk/cows_wps/controllers/admin.py

    r7097 r7115  
    11import logging 
    2 import re 
    32 
    43from pylons import request, response, session, tmpl_context as c 
    54from pylons.controllers.util import abort, redirect_to 
    65 
     6from cows_wps.model.managers import requestManager 
     7from cows_wps.model.orm import tables 
     8 
    79from cows_wps.renderer.ui_renderer import * 
    810from cows_wps.controllers import * 
    911from cows_wps.lib.ui.proc_config import * 
    10  
    11 from cows_wps.model.managers import requestManager 
    12 from cows_wps.process_handler.context.process_status import STATUS 
    13 from cows_wps.process_handler.validate_arguments import parseDateTime 
    1412 
    1513log = logging.getLogger(__name__) 
     
    1917 
    2018    def index(self): 
     19        sess = requestManager.getSession() 
     20        res = sess.query(tables.admin)[0] 
     21        admin_u = str(res.admin_name) 
     22        admin_p = str(res.admin_password) 
     23 
     24        admin_name = None 
     25        admin_password = None 
     26   
     27        if "admin_name" in request.params.keys(): 
     28            admin_name = str(request.params.getone("admin_name")) 
     29        if "admin_password" in request.params.keys(): 
     30            admin_password = str(request.params.getone("admin_password")) 
     31 
     32        err_msg = "" 
     33 
     34        if admin_name != None: 
     35            if admin_name != admin_u or admin_password == None:  
     36                err_msg = "Incorrect login details provided. Please try again." 
     37                return self.login(err_msg = err_msg) 
     38            else: 
     39                if admin_password != admin_p: 
     40                    err_msg = "Incorrect login details provided. Please try again." 
     41                    return self.login(err_msg = err_msg) 
     42                else: 
     43                    return self._successfulLogin() 
     44        else: 
     45            return self.login() 
    2146         
    22         return "Welcome to the admin interface."  
    23      
    24     def _parseArgs(self): 
    25         args = {} 
    26         bad_args = {} 
    27      
    28         for (key, default) in self.default_args.items(): 
    29             value = None 
    30             if request.params.has_key(key): 
    31                 value = str(request.params.getone(key)) 
    32              
    33                 # If arg_check is False then bad input 
    34                 arg_check = apply(self.arg_processers[key], [value]) 
    35                 if arg_check == False: 
    36                     bad_args[key] = value 
    37                     value = default 
    38                 else: 
    39                     value = arg_check 
    40             else: 
    41                 value = default 
    42              
    43             args[key] = value 
    44              
    45         return (args, bad_args) 
    46      
    4747 
    48     def _orderJobs(self, jobs, order_by): 
    49         reverse = False 
     48    def _successfulLogin(self): 
     49        response.set_cookie('wps_ui_admin', request.environ["REMOTE_ADDR"], expires = 3600) 
     50        html = """<p>You have successfully logged in.</p><p>Please try using the <a href="/jobs">jobs page</a> to view and manage everyone's jobs.</p>""" 
     51        renderer = UIPageRenderer() 
     52        resp = renderer.render("Administrator page", 
     53                               [("Administrator", html)], 
     54                               admin = True) 
     55        return resp 
    5056 
    51         if order_by.find("_rev") > -1: 
    52             order_by = order_by.replace("_rev", "") 
    53             reverse = True 
    5457 
    55         indx = self.job_item_order[order_by]  
    56         tmp_jobs = [(job[indx], job[:]) for job in jobs] 
    57         tmp_jobs.sort() 
     58    def login(self, err_msg = ""): 
     59        """ 
     60        Show admin login page. 
     61        """ 
     62        login_form = "" 
    5863 
    59         if reverse: 
    60             tmp_jobs.reverse() 
    61           
    62         ordered_jobs = [i[1] for i in tmp_jobs] 
    63         return ordered_jobs 
    64      
    65      
    66     def _filterJobs(self, start, n_records, job_desc_match, job_id_match, 
    67                     job_type, job_status, sub_before, sub_after, order_by): 
    68         # Get all jobs at start 
    69         requests = requestManager.getAllRequest() 
     64        if err_msg != "": 
     65            login_form = """<center><div id="bad_login" style="width: 600px; border-width: 0px; background: orange; color: white; font-weight: bold; padding: 3px;">%s</div></center>""" % err_msg 
     66 
     67        login_form += """<form action="/admin" onSubmit="return validateTextInput(document.getElementById('admin_name').value, /^[a-zz0-9A-Z]{4,20}$/, 'The user name must be between 4 and 20 letters and/or numbers.');" >  
     68                <p>Please enter your details</p> 
     69                <label class="text_width_150"><b>Username: </b></label> 
     70                <input type="text" name="admin_name" id="username" value="" size="20" /><br /> 
     71                <label class="text_width_150"><b>Password: </b></label> 
     72                <input type="password" name="admin_password" value="" size="20" />&nbsp;&nbsp; 
     73                <input type="submit" value="Login" /> 
     74        </form> 
     75        """ 
     76        renderer = UIPageRenderer() 
     77        resp = renderer.render("Administrator page",  
     78                               [("Login", login_form)]) 
     79        return resp 
    7080        
    71         # Define jobs as tuple of (job_id, user, status, job_type, created)  
    72         # And convert all unicodes 
    73         jobs = [[str(i) for i in (r.job_id, r.user_id, r.job.status, r.job.type, r.job.created)] for r in requests] 
    74           
    75         for filtr in ("job_id_match", "job_type", "job_status", "sub_before", "sub_after"): 
    76             jobs = self._filterBy(jobs, filtr, filter_value = vars()[filtr]) 
    77         
    78         total_matches = len(jobs)         
    79         ordered_jobs = self._orderJobs(jobs, order_by)[start:(start + n_records)] 
    80         return (ordered_jobs, total_matches) 
    81      
    82      
    83     def _filterBy(self, jobs, filtr, filter_value): 
    84         # Represent jobs as lists of properties 
    85         if filter_value == None: 
    86             return jobs 
    87          
    88         indx = self.job_item_order[filtr] 
    89         test_param = None 
    90         filter_type = self.filter_types[filtr] 
    91         filtered_jobs = [] 
    92  
    93         for job in jobs: 
    94          
    95             item = job[indx] 
    96          
    97             if filter_type == "regex": 
    98                 if not test_param: 
    99                     test_param = re.compile(filter_value) 
    100          
    101                 if test_param.search(item): 
    102                     filtered_jobs.append(job) 
    103              
    104             elif filter_type.find("time:") == 0: 
    105                 if not test_param: 
    106                     test_param = filter_value 
    107          
    108                 when = filter_type.split(":")[1].strip() 
    109          
    110                 if when == "after": 
    111                     if item > test_param: 
    112                         filtered_jobs.append(job) 
    113              
    114                 elif when == "before": 
    115                     if item < test_param: 
    116                         filtered_jobs.append(job) 
    117              
    118             elif filter_type == "equality": 
    119                 if filter_value == item: 
    120                     filtered_jobs.append(job) 
    121              
    122             elif filter_type == "contains": 
    123 #                raise str(str(item) + str(filter_value)) 
    124                 if item in filter_value: 
    125                     filtered_jobs.append(job) 
    126  
    127         return filtered_jobs 
    128  
     81    def logout(self): 
     82        return str(dir(request.params["wps_ui_admin"])) 
     83        return self.login(err_msg = "You have successfully logged out.") 
  • cows_wps/trunk/cows_wps/controllers/jobs.py

    r7106 r7115  
    6262class JobsController(BaseController): 
    6363 
    64     job_item_order = {"job_id_match": 0, "user_id": 1, "job_status": 2, 
     64    job_item_order = {"job_id_match": 0, "user_id_match": 1, "job_status": 2, 
    6565                      "job_type": 3, "sub_before": 4, "sub_after": 4, 
    6666                      "job_id": 0, "sub_time": 4} 
     
    7272            "sub_after": "time:after", 
    7373            "sub_before": "time:before", 
    74             "user_id": "equality", 
     74            "user_id_match": "regex", 
    7575            } 
    7676 
    7777    default_args = {"start": 0, 
    78                     "n_records": 20, 
     78                    "n_records": 500, 
    7979            "job_desc_match": None, 
    8080            "job_id_match": None, 
     
    8383            "sub_before": None, 
    8484            "sub_after": None, 
     85            "user_id_match": None, # for admin only 
    8586            "order_by": "sub_time_rev"} 
    8687 
     
    9394            "sub_before": toDateTime, 
    9495            "sub_after": toDateTime, 
     96            "user_id_match": str, 
    9597            "order_by": checkValidOrderBy} 
    9698 
    9799 
    98100    def index(self): 
    99         (args, bad_args) = self._parseArgs() 
    100         user_id = request.environ["REMOTE_USER"].split("/")[-1] 
    101         args["user_id"] = user_id 
     101        # Check if admin is True 
     102        admin = False 
     103        admin_cookie = request.cookies.get("wps_ui_admin", None) 
     104#        return str(admin_cookie) 
     105 
     106        if admin_cookie and admin_cookie == request.environ["REMOTE_ADDR"]: 
     107            admin = True 
     108 
     109        (args, bad_args) = self._parseArgs(admin = admin) 
     110 
     111        if admin == False: 
     112            try: 
     113                user_id = request.environ["REMOTE_USER"].split("/")[-1] 
     114                args["user_id_match"] = user_id 
     115            except: 
     116                raise Exception("Jobs page is only visible to a valid user or system administrator.  Please login.") 
     117        else: 
     118            user_id = None 
    102119 
    103120#        return (str(args) + "----" + str(bad_args)) 
     
    105122 
    106123        renderer = UIPageRenderer() 
    107         return renderer.renderJobsPage(user_id, filtered_jobs, total_matches, args, bad_args) 
    108      
    109      
    110     def _parseArgs(self): 
     124        return renderer.renderJobsPage(filtered_jobs, total_matches, args, bad_args, user_id = user_id, admin = admin) 
     125     
     126     
     127    def _parseArgs(self, admin = False): 
    111128        args = {} 
    112129        bad_args = {} 
    113130     
    114131        for (key, default) in self.default_args.items(): 
     132 
     133            if not admin and key == "user_id_match": 
     134                continue 
     135 
    115136            value = None 
    116137 
     
    154175     
    155176     
    156     def _filterJobs(self, user_id, start, n_records, job_desc_match, job_id_match, 
     177    def _filterJobs(self, user_id_match, start, n_records, job_desc_match, job_id_match, 
    157178                    job_type, job_status, sub_before, sub_after, order_by): 
    158179        # Get all jobs at start 
     
    163184        jobs = [[str(i) for i in (r.id, r.user_id, r.job.status, r.job.type, r.job.created)] for r in requests] 
    164185          
    165         for filtr in ("job_id_match", "job_type", "job_status", "sub_before", "sub_after", "user_id"): 
     186        for filtr in ("job_id_match", "job_type", "job_status", "sub_before", "sub_after", "user_id_match"): 
    166187            jobs = self._filterBy(jobs, filtr, filter_value = vars()[filtr]) 
    167188        
  • cows_wps/trunk/cows_wps/controllers/test.py

    r7082 r7115  
    1111from cows_wps.controllers import * 
    1212from cows_wps.lib.ui.proc_config import * 
     13from cows_wps.model.managers import requestManager 
     14from cows_wps.model.orm import tables 
    1315 
    1416from cows_wps.utils.user_roles_dict import user_roles_config_dict 
     
    108110 
    109111        return resp 
     112 
     113    def dbtest(self): 
     114        sess = requestManager.getSession() 
     115        res = sess.query(tables.admin)[0] 
     116        admin_u = res.admin_name 
     117        admin_p = res.admin_password 
     118        return str(admin_u + "::" + admin_p) 
  • cows_wps/trunk/cows_wps/model/orm/classes.py

    r5615 r7115  
    123123        h.update(key) 
    124124        return h.digest() 
    125          
     125 
     126 
     127class Admin(object): 
     128    def __init__(self, admin_name, admin_password): 
     129        self.admin_name = admin_name 
     130        self.admin_password = admin_password 
    126131 
    127132# 
     
    146151       properties={'job': relation(Job)} 
    147152) 
     153mapper(Admin, tables.admin) 
  • cows_wps/trunk/cows_wps/model/orm/tables.py

    r5615 r7115  
    4646) 
    4747 
     48admin = Table('admin', metadata, 
     49        Column('admin_name', String(16), primary_key = True), 
     50        Column('admin_password', String(16))) 
  • cows_wps/trunk/cows_wps/model/session.py

    r5615 r7115  
    1313 
    1414db_url = wps_config_dict['database_url'] 
     15#db_url = "postgresql://ceda_wps:wasp_ced@bora/ceda_wps_test" 
    1516log.info('Initialising database engine %s' % db_url) 
    1617engine = create_engine(db_url) 
  • cows_wps/trunk/cows_wps/public/style/wps_ui.css

    r6910 r7115  
    121121} 
    122122 
     123.header_row { 
     124        background-color: #99ccff; 
     125        font-weight: bold; 
     126} 
     127 
     128.highlighted_row { 
     129        background-color: #44ff44; 
     130} 
     131 
    123132.odd_row { 
    124         background-color: #eeeeee; 
     133        background-color: #dddddd; 
    125134} 
    126135 
  • cows_wps/trunk/cows_wps/renderer/ui_renderer.py

    r7106 r7115  
    3434        return new_items 
    3535 
    36     def render(self, title, items, bbox_required=False): 
     36    def render(self, title, items, admin = False, bbox_required = False): 
    3737        """ 
    3838        Renders the page using title and then a list of tuples of 
     
    4242        # Make sure items are HTML and won't be escaped 
    4343        items = self._htmlifyItems(items) 
    44         stream = tmpl_gen.generate(title=title, items=items,  
    45                         wps_capabilities_url="/wps?Service=WPS&Request=GetCapabilities&Format=text/xml", 
    46                         bbox_required=bbox_required) 
     44        stream = tmpl_gen.generate(title = title, items = items,  
     45                        wps_capabilities_url = "/wps?Service=WPS&Request=GetCapabilities&Format=text/xml", 
     46                        admin = admin, bbox_required = bbox_required) 
    4747        return stream.render('xhtml') 
    4848 
    4949 
    50     def renderJobsPage(self, user_id, jobs, total_matches, args, bad_args): 
     50    def renderJobsPage(self, jobs, total_matches, args, bad_args, user_id, admin = False): 
    5151        """ 
    5252        Renders jobs page. 
     53        if ``admin`` is True then this is an administrator who can view all user jobs,  
     54        and cancel them! 
    5355        """ 
    5456        jobs_html = '<b>Total jobs matched: <span style="background: white; border: solid 1px; padding: 3px;">%d</span></b><br/><br/>' % total_matches 
    55         jobs_html += self._renderJobsTable(user_id, jobs) 
     57        jobs_html += self._renderJobsTable(jobs, user_id, admin = admin) 
    5658  
    5759        filter_html = "Please select the filtering options and press the 'Filter jobs' button to submit the new filter settings." 
     
    6567            filter_html += '<center><div id="incorrect_arguments" style="width: 600px; border-width: 0px; background: orange; color: white; font-weight: bold; padding: 3px;">%s</div></center>' % msg  
    6668 
    67         filter_html += self._renderFilterOptions(args) 
     69        filter_html += self._renderFilterOptions(args, admin = admin) 
    6870 
    6971  
     
    7274                 ("Jobs", jobs_html)]   
    7375 
    74         return self.render("Jobs Page", items) 
     76        return self.render("Jobs Page", items, admin = admin) 
    7577 
    7678 
    77     def _renderJobsTable(self, user_id, jobs): 
    78         "Renders and returns (as string) table of HTML jobs." 
     79    def _renderJobsTable(self, jobs, user_id = None, admin = False): 
     80        """ 
     81        Renders and returns (as string) table of HTML jobs. 
     82        if ``user_id`` matches user in job list then allow view/download or cancel. 
     83        if ``admin`` is True then you can view/cancel any job. 
     84        """ 
     85        if user_id == None and admin == False: 
     86            raise Exception("_renderJobsTable requires either user_id or admin arg to be set, neither is.") 
     87 
    7988        html = """ 
    8089<table border="2"> 
    81         <tr> 
     90        <tr class="header_row"> 
    8291                <td>Request ID</td> 
    8392                <td>Job type</td> 
     
    98107 
    99108            # Set action 
    100             status_url = "http://" + request.environ["HTTP_HOST"] + url_for(controller = 'status', requestId = req_id)  
    101             job_viewer_url = url_for(controller = 'jobviewer') + "?status_url=" + status_url 
    102             action = '<a href="%s">View job info/outputs</a>' % job_viewer_url 
     109            action = "" 
    103110 
    104             if status in ("STARTED", "ACCEPTED"): 
    105                 cancel_url = url_for(controller = "user", action = "cancel", userId = user_id, jobId = req_id)  
    106                 action += '<br/><a href="%s">Cancel this job</a>' % cancel_url 
     111            # Allow extra actions if user_id matches job user 
     112            if user_id == user or admin == True: 
     113 
     114                # Define jobsviewer page 
     115                status_url = "http://" + request.environ["HTTP_HOST"] + url_for(controller = 'status', requestId = req_id)  
     116                job_viewer_url = url_for(controller = 'jobviewer') + "?status_url=" + status_url 
     117                action += '<a href="%s">View job info/outputs</a>' % job_viewer_url 
     118 
     119                # If running allow cancellation 
     120                if status in ("STARTED", "ACCEPTED"): 
     121                    cancel_url = url_for(controller = "user", action = "cancel", userId = user, jobId = req_id)  
     122                    action += '<br/><a href="%s">Cancel this job</a>' % cancel_url 
     123                    row_style = "highlighted_row" 
    107124 
    108125            # HTML for row 
     
    114131 
    115132 
    116     def _renderFilterOptions(self, args): 
     133    def _renderFilterOptions(self, args, admin = False): 
    117134        """ 
    118135        Returns a string for the rendered HTML for filter form. 
     136        if ``admin` is True allow filtering on user id. 
    119137        """ 
    120138        fr = FormRenderer() 
    121139 
    122         filters = [("job_id_match", {"type": "text", "regex": "any", "text": "Job ID matches", "default": ""}), 
     140        filters = [("job_id_match", {"type": "text", "regex": "any", "text": "Job ID matches (regular expression)", "default": ""}), 
    123141                   ("job_status", {"type": "list", "text": "Job Status", "default": "-- Please select --", 
    124142                         "optional": True, "multiple": False, 
     
    133151                         "Job submitted after (format: YYYY-MM-DDThh:mm:ss)", "default": ""}), 
    134152                  ] 
     153 
     154        if admin == True: 
     155            filters.append( ("user_id_match", {"type": "text", "regex": "any", "text": "User ID matches (regular expression)", "default": ""}) ) 
    135156 
    136157        html = '<form name="filter_form" action="jobs">' 
  • cows_wps/trunk/cows_wps/templates/ui_template.html

    r7010 r7115  
    103103                <?python username = logged_in.getUserName() ?> 
    104104                <a href="/logout">Logout</a>  
    105                 (logged in as: ${username}) 
     105                [ You are: ${username} 
    106106        </py:if> 
    107107        <py:if test="logged_in == False"> 
    108108                <a href="/login">Login</a> 
    109109        </py:if> 
     110 
     111        <py:if test="admin"> 
     112                (Administrator) 
     113        </py:if> 
     114        ] 
     115                 
    110116 
    111117        </div> 
  • cows_wps/trunk/cows_wps/websetup.py

    r6877 r7115  
    3535 
    3636    tables.metadata.create_all(engine) 
    37  
     37#    tables.admin.create(engine) 
    3838    print 'Done' 
    3939     
Note: See TracChangeset for help on using the changeset viewer.