Skip to content

Commit

Permalink
Manually merge PR176: Minimal per-user account page
Browse files Browse the repository at this point in the history
git-svn-id: svn+ssh://svn.code.sf.net/p/migrid/code/trunk@6193 b75ad72c-e7d7-11dd-a971-7dbc132099af
  • Loading branch information
jonasbardino committed Jan 10, 2025
1 parent 3cac362 commit ae482d1
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 13 deletions.
6 changes: 3 additions & 3 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -716,7 +716,7 @@ additional web apps and OpenID on CentOS:
--signup_methods="extoid migoid migcert extoidc" \
--login_methods="extoid migoid migcert extoidc" \
--distro=centos --skin=migrid-basic \
--default_menu="home files submitjob jobs vgrids settings setup logout" \
--default_menu="home files submitjob jobs vgrids account settings setup logout" \
--user_menu="sharelinks people cloud crontab transfers runtimeenvs resources peers downloads docs dashboard migadmin" \
--wsgi_procs=25 --sftp_subsys_auth_procs=20 \
--sftp_max_sessions=16 \
Expand Down Expand Up @@ -820,7 +820,7 @@ local OpenID login and added Jupyter+cloud integration for data analysis:
--davs_port=8020 --openid_port=8001 \
--wsgi_procs=100 --sftp_subsys_auth_procs=50 \
--sftp_max_sessions=16 \
--default_menu="home files vgrids archives jupyter settings setup logout" \
--default_menu="home files vgrids archives jupyter account settings setup logout" \
--user_menu="sharelinks seafile crontab transfers cloud people downloads peers docs migadmin" \
--collaboration_links="default advanced" \
--default_vgrid_links="files web" \
Expand Down Expand Up @@ -908,7 +908,7 @@ local OpenID login and support for legacy sftp clients:
--wsgi_procs=25 --sftp_subsys_auth_procs=25 \
--sftp_max_sessions=16 \
--davs_port=8020 --openid_port=8001 \
--default_menu="home files submitjob jobs vgrids jupyter settings setup logout" \
--default_menu="home files submitjob jobs vgrids jupyter account settings setup logout" \
--user_menu="sharelinks people cloud crontab transfers runtimeenvs resources downloads peers docs migadmin" \
--collaboration_links="default advanced" \
--default_vgrid_links="files web" \
Expand Down
4 changes: 2 additions & 2 deletions mig/assets/css/V3/nav.css
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@
.popup-container {
position: fixed;
width: 270px;
height: 300px;
height: 340px;
background-color: #FFF;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);
border-radius: 8px;
Expand Down Expand Up @@ -504,7 +504,7 @@
}

.popup-middle {
height: 180px;
height: 220px;
width: 100%;
border-bottom: 1px solid #EEE;
padding: 10px;
Expand Down
34 changes: 34 additions & 0 deletions mig/cgi-bin/account.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# --- BEGIN_HEADER ---
#
# account - account page front end
# Copyright (C) 2003-2024 The MiG Project by the Science HPC Center at UCPH
#
# This file is part of MiG.
#
# MiG is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# MiG 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# -- END_HEADER ---
#

from __future__ import absolute_import
import cgi

from mig.shared.functionality.account import main
from mig.shared.cgiscriptstub import run_cgi_script_possibly_with_cert

run_cgi_script_possibly_with_cert(main)
8 changes: 4 additions & 4 deletions mig/shared/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -1944,10 +1944,10 @@ def reload_config(self, verbose, skip_log=False, disable_auth_log=False,
req = config.get('SITE', 'default_menu').split()
self.site_default_menu = [i for i in req if i in menu_items]
else:
self.site_default_menu = ['home', 'files', 'submitjob',
'jobs', 'resources', 'vgrids',
'downloads', 'runtimeenvs', 'people',
'settings', 'crontab', 'docs', 'logout']
self.site_default_menu = ['home', 'files', 'submitjob', 'jobs',
'resources', 'vgrids', 'downloads',
'runtimeenvs', 'people', 'settings',
'crontab', 'account', 'docs', 'logout']
if config.has_option('SITE', 'simple_menu'):
req = config.get('SITE', 'simple_menu').split()
self.site_simple_menu = [i for i in req if i in menu_items]
Expand Down
184 changes: 184 additions & 0 deletions mig/shared/functionality/account.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# --- BEGIN_HEADER ---
#
# account - account page with info and account management options
# Copyright (C) 2003-2024 The MiG Project by the Science HPC Center at UCPH
#
# This file is part of MiG.
#
# MiG is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# MiG 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# -- END_HEADER ---
#


"""Account page with user details and account management options"""

from __future__ import absolute_import

import datetime
import os

from mig.shared import returnvalues
from mig.shared.functional import validate_input_and_cert
from mig.shared.init import initialize_main_variables, find_entry
from mig.shared.htmlgen import html_user_messages, man_base_html, man_base_js
from mig.shared.useradm import get_full_user_map

_account_field_order = [('full_name', 'Full Name'),
('organization', 'Organization'),
('email', 'Email Address'),
('country', 'Country'),
('role', 'Role'),
('status', 'Account Status'),
('expire', 'Expire'),
('peers_full_name', 'Peer Full Name(s)'),
('peers_email', 'Peer Email Address(es)'),
]


def html_tmpl(configuration, client_id, environ, title_entry):
"""HTML page base: some account and manage actions depend on configuration
and environ.
"""

user_msg, show_user_msg = '', 'hidden'
if configuration.site_enable_user_messages:
user_msg = html_user_messages(configuration, client_id)
show_user_msg = ''
user_map = get_full_user_map(configuration)
user_dict = user_map.get(client_id, None)
user_account = ''
if user_dict:
user_account += '''
<h3>Account Details</h3>
<p class="sub-title">Your account has the following information
registered:
</p>
'''
for (field, label) in _account_field_order:
if not user_dict.get(field, False):
continue
if field == 'expire':
# NOTE: translate epoch to proper datetime string
expire_dt = datetime.datetime.fromtimestamp(user_dict[field])
user_dict[field] = expire_dt
user_account += '''%s: %s<br/>
''' % (label, user_dict[field])
# NOTE: ID token is only available for openid connect
claim_dump, user_token = '', ''
for (key, val) in os.environ.items():
if key.startswith('OIDC_CLAIM_'):
claim_dump += "%s: %s<br/>" % (key, val)
if claim_dump:
user_token = '''
<h3>ID Token</h3>
<p class="sub-title">Your current login session provides the following
additional information:
</p>'''
user_token += claim_dump
fill_helpers = {'short_title': configuration.short_title,
'user_msg': user_msg, 'show_user_msg': show_user_msg,
'user_account': user_account,
'user_token': user_token}

html = '''
<!-- CONTENT -->
<div class="container">
<div id="account-container" class="row">
''' % fill_helpers
html += '''
<div id="user-account-container" class="col-12 invert-theme">
<div id="user-account-content" class="user-account-placeholder">
%(user_account)s
</div>
<div id="user-token-content" class="user-token-placeholder">
%(user_token)s
</div>
<div id="user-data-content" class="user-data-placeholder">
<p>Details are from your sign up and/or any updates provided
through your login. Please contact support if something is
incorrect or has significantly changed.
</p>
</div>
</div>
''' % fill_helpers
html += '''
<div id="user-msg-container" class="col-12 invert-theme %(show_user_msg)s">
<div id="user-msg-content" class="user-msg-placeholder">
%(user_msg)s
</div>
</div>
''' % fill_helpers
html += '''
<div class="col-lg-12 vertical-spacer"></div>
</div>
'''

# TODO: add account management actions

return html


def signature():
"""Signature of the main function"""

defaults = {}
return ['text', defaults]


def main(client_id, user_arguments_dict, environ=None):
"""Main function used by front end"""

if environ is None:
environ = os.environ

(configuration, logger, output_objects, op_name) = \
initialize_main_variables(client_id, op_header=False,
op_menu=client_id)
defaults = signature()[1]
(validate_status, accepted) = validate_input_and_cert(
user_arguments_dict,
defaults,
output_objects,
client_id,
configuration,
allow_rejects=False,
)
if not validate_status:
return (accepted, returnvalues.CLIENT_ERROR)

# Generate and insert the page HTML
title_entry = find_entry(output_objects, 'title')
title_entry['text'] = '%s Profile' % configuration.short_title

# jquery support for AJAX saving

(add_import, add_init, add_ready) = man_base_js(configuration, [])
add_init += '''
'''
add_ready += '''
init_user_msg();
'''
title_entry['script']['advanced'] += add_import
title_entry['script']['init'] += add_init
title_entry['script']['ready'] += add_ready

html = html_tmpl(configuration, client_id, environ, title_entry)
output_objects.append({'object_type': 'html_form', 'text': html})

return (output_objects, returnvalues.OK)
12 changes: 8 additions & 4 deletions mig/shared/htmlgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,15 @@
menu_items['archives'] = {'class': 'archives fas fa-archive', 'url': 'freezedb.py',
'title': 'Archives',
'hover': 'Frozen archives: write-once file archives'}
menu_items['account'] = {'class': 'account fas fa-account', 'url': 'account.py',
'legacy_only': True, 'title': 'Account',
'hover': 'Account info and management'}
menu_items['settings'] = {'class': 'settings fas fa-user', 'url': 'settings.py',
'legacy_only': True, 'title': 'Settings',
'hover': 'Your personal settings for these pages'}
menu_items['setup'] = {'class': 'setup fas fa-user-cog', 'url': 'setup.py',
'legacy_only': True, 'title': 'Setup',
'hover': 'Your client access settings for this site'}
'hover': 'Your client access setup for this site'}
menu_items['transfers'] = {'class': 'transfers fas fa-datatransfer', 'url': 'datatransfer.py',
'title': 'Data Transfers',
'hover': 'For background batch transfers of data'}
Expand Down Expand Up @@ -2061,7 +2064,7 @@ def get_xgi_html_header(
for user_entry in ['logout', 'help']:
profile_helper['disable%s' % user_entry] = ''
# Disable any other entries missing from base and user menu
for user_entry in ['home', 'settings', 'setup']:
for user_entry in ['home', 'account', 'settings', 'setup']:
profile_helper['disable%s' % user_entry] = ''
if not user_entry in base_menu + user_menu:
profile_helper['disable%s' %
Expand All @@ -2085,9 +2088,10 @@ def get_xgi_html_header(
</div>
<div class="popup-middle col-12">
<a class="user-menu__item link-home %(disablehome)s" href="home.py">Home</a>
<a class="user-menu__item link-account %(disableaccount)s" href="account.py">Account</a>
<a class="user-menu__item link-settings %(disablesettings)s" href="settings.py">Settings</a>
<a class="user-menu__item link-setup %(disablesetup)s " href="setup.py">Setup</a>
<a class="user-menu__item link-help %(disablehelp)s " href="%(help_url)s">Help</a>
<a class="user-menu__item link-setup %(disablesetup)s" href="setup.py">Setup</a>
<a class="user-menu__item link-help %(disablehelp)s" href="%(help_url)s">Help</a>
</div>
<div class="popup-footer col-12">
<a class="user-menu__item link-logout %(disablelogout)s " href="logout.py">Sign Out</a>
Expand Down

0 comments on commit ae482d1

Please sign in to comment.