Republishing of FIC2014 challenges

This commit is contained in:
nemunaire 2021-10-06 11:33:24 +02:00
parent 939e6d994d
commit c54f929846
24 changed files with 329 additions and 117 deletions

26
Dockerfile Normal file
View File

@ -0,0 +1,26 @@
# /!\ WARNING: the container generated through this Dockerfile is made only for development purpose; it is NOT SAFE or production ready.
FROM php:5.5-fpm-alpine
MAINTAINER Pierre-Olivier Mercier <nemunaire@nemunai.re>
# Install packages ####################################################
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
RUN chmod +x /usr/local/bin/install-php-extensions && \
install-php-extensions mysql mcrypt
# ENVIRONNEMENT #######################################################
EXPOSE 80/tcp 443/tcp
VOLUME ["/var/www/fic-server/out","/var/www/fic-server/files","/var/www/fic-server/submission","/var/www/fic-server/shared"]
WORKDIR /var/www/fic-server
ENTRYPOINT ["/var/www/fic-server/entrypoint.sh"]
CMD ["php-fpm"]
# Copying files #######################################################
COPY . /var/www/fic-server/

16
config.sh Normal file
View File

@ -0,0 +1,16 @@
# Username of the unpriviledge user that runs scripts
SYNCHRO_USER="synchro"
BASEDIR="/var/www/fic-server"
# Directory where backup should be made
if [ -z "$TO_BCKP" ]
then
TO_BCKP="/mnt/backup"
fi
# Password of the MySQL user backup (with RO rights)
if [ -z "$BCKP_PASS" ]
then
BCKP_PASS="Riuy6of sae^W0Sh"
fi

51
entrypoint.sh Executable file
View File

@ -0,0 +1,51 @@
#!/bin/sh
# Docker entrypoint
cd `dirname "$0"`
. ./config.sh
# Creating directory and set permissions
mkdir -p ${BASEDIR}/logs ${BASEDIR}/onyx/log
chown -R www-data:www-data ${BASEDIR}/pki ${BASEDIR}/PKI ${BASEDIR}/onyx/log
chown -R ${SYNCHRO_USER}:www-data ${BASEDIR}/submission ${BASEDIR}/logs ${BASEDIR}/out
chmod 770 ${BASEDIR}/submission
chown ${SYNCHRO_USER} ${BASEDIR}/.ssh/id_rsa
chown www-data:www-data ${BASEDIR}/shared ${BASEDIR}/shared/crl.pem
# Update database profile
cat <<EOF > ${BASEDIR}/onyx/db/docker.profile.php &&
<?php
if(!defined('ONYX')) exit;
\$___profile['db'] = '$DB_ENV_MYSQL_DATABASE';
\$___profile['host'] = '$DB_PORT_3306_TCP_ADDR';
\$___profile['user'] = '$DB_ENV_MYSQL_USER';
\$___profile['pass'] = '$DB_ENV_MYSQL_PASSWORD';
EOF
sed -i 's/"profile">sample</"profile">docker</' ${BASEDIR}/onyx/config/root.xml
# Development version?
if [ -n "$DEVELOPMENT" ]
then
echo -e "\033[1;31mDEVELOPMENT version ENABLED\033[0m"
sed -i 's/<var name="development">0</<var name="development">1</' ${BASEDIR}/onyx/config/root.xml
if [ "$DEVELOPMENT" -gt 0 ]
then
sed -i 's/<env option="\(display.*_errors\)">0</<env option="\1">1</' ${BASEDIR}/onyx/config/root.xml
fi
else
echo -e "\033[32mLaunched as PRODUCTION version\033[0m"
fi
# Generate hashed path for files
echo -n 'Copying files... '
${BASEDIR}/gen_hash_link_files.sh --copy ${BASEDIR}/files-in ${BASEDIR}/files
echo -e "\033[32mdone\033[0m"
echo -e "\033[1;33mYou should run in background:\033[0m tail -f ./logs/checks.log &"
# Continue execution
exec "$@"

View File

@ -46,7 +46,7 @@ cd "$MYTMPDIR"
# First, remove existing version if any
rm -rf "$BASEURL" "$OUT_TEAM"
wget $WGET_OPT -m -b "http://$BASEURL/" -o /dev/null
wget $WGET_OPT -m -b "http://$BASEURL:8080/" -o /dev/null
mkdir -p "$BASEURL"
ln -sf "$ORIG_DIR/files/" "$BASEURL/files"
@ -62,7 +62,7 @@ then
done
FULLSYNC=0
else
for l in $(curl -k "http://$BASEURL/$SALT_TEAM/" 2> /dev/null | grep -oE "/[^/]+/[0-9]+/")
for l in $(curl -k "http://$BASEURL:8080/$SALT_TEAM/" 2> /dev/null | grep -oE "/[^/]+/[0-9]+/")
do
TEAMS="$TEAMS $l"
done
@ -77,24 +77,23 @@ PIDLIST=
for l in $TEAMS
do
(
if ! wget $WGET_OPT -m "http://$BASEURL/$l"
if ! wget $WGET_OPT -m "http://$BASEURL:8080/$l"
then
exit 1
fi
for m in $(grep -R "<form " "$BASEURL/$l" | grep -oE "/[^/]+/([^/]+)/([0-9]+)-[^/]+/([a-zA-Z0-9_]+)/submission")
for m in $(grep -R "<form " "$BASEURL:8080/$l" | grep -oE "[^/]+/([^/]+)/([0-9]+)-[^/]+/([a-zA-Z0-9_]+)/submission")
do
OUT=`echo "$m" | sed -E 's#/([^/]+)/([^/]+)/([0-9]+)-[^/]+/([a-zA-Z0-9_]+)/submission#\1/\2/submission-\3-\4#'`
wget $WGET_OPT "http://$BASEURL/$m" -O "$BASEURL/$OUT.html"
wget $WGET_OPT "http://$BASEURL/$m/gerr" -O "$BASEURL/$OUT-bad.html"
wget $WGET_OPT "http://$BASEURL/$m/serr" -O "$BASEURL/$OUT-already.html"
OUT=`echo "$m" | sed -E 's#([^/]+)/([^/]+)/([0-9]+)-[^/]+/([a-zA-Z0-9_]+)/submission#\1/\2/submission-\3-\4#'`
wget $WGET_OPT "http://$BASEURL:8080/$m" -O "$BASEURL/$OUT.html"
wget $WGET_OPT "http://$BASEURL:8080/$m/gerr" -O "$BASEURL/$OUT-bad.html"
wget $WGET_OPT "http://$BASEURL:8080/$m/serr" -O "$BASEURL/$OUT-already.html"
done
# Remove /connected/XY
for f in `find "$BASEURL/$l" -type f`
for f in `find "$BASEURL:8080/$l" -type f`
do
sed -Ei "s#/[^/]+/([0-9]+)/#/#" "$f" &&
sed -Ei "s#/([0-9]+)-[^/]*/([a-zA-Z0-9_]+)/submission#/submission-\1-\2.html#" "$f"
sed -Ei "s#([0-9]+)-[^/]*/([a-zA-Z0-9_]+)/submission#submission-\1-\2.html#;s#[^/\"]+/([0-9]+)/##" "$f"
done
) &
@ -144,7 +143,7 @@ then
else
MOREOPT=
if [ "$FULL" -eq "1" ]
if [ "$FULL" = "1" ]
then
MOREOPT="--delete"
fi

View File

@ -30,6 +30,17 @@
text-shadow: 0 0 5px #00c6ff;
}
.samptest {
display: block !important;
overflow-x: scroll;
text-overflow: ellipsis;
}
samp {
display: block;
overflow-x: auto;
text-overflow: ellipsis;
}
.point {
position: relative;
-moz-animation: mymove 1s ease infinite;

View File

@ -131,7 +131,7 @@ else if ($n && $p[0] == SALT_USER)
$page = "teams/list";
}
else if (empty($VAR["start_challenge"]))
else if (!empty($p[1]) && empty($VAR["start_challenge"]))
{
$TEAM = new Team($p[1]);
$template->assign("my_team", $TEAM);
@ -141,6 +141,17 @@ else if ($n && $p[0] == SALT_USER)
$page = "teams/lobby";
}
else if (!empty($p[1]) && time() > $VAR["end_challenge"])
{
$TEAM = new Team($p[1]);
$template->assign("my_team", $TEAM);
$template->assign("themes", Theme::get_themes());
$template->assign("rank", Team::get_top());
require("team/summary.php");
$page = "teams/end";
}
else
{
$TEAM = new Team($p[1]);

View File

@ -19,5 +19,6 @@ if (!empty($themes))
$template->assign("themes", Theme::get_themes());
$template->assign("nbExoMax", Exercice::get_nb_exo_max());
$template->assign("percent", $percent);
$template->assign("rank", Team::get_top());
return "teams/summary";

View File

@ -3,6 +3,10 @@
{if isset($ex)}
<h2>{$theme->name} <small>{$ex->id}</small></h2>
<form role="form" method="post" action="/{$SALT_ADMIN}/ex/{$theme->id}-{$theme->name}/{$ex->id}">
<div class="form-group">
<label for="title">Titre</label>
<input type="text" class="form-control" value="{$ex->title|escape}" name="title" id="title">
</div>
<div class="form-group">
<label for="desc">Description</label>
<textarea class="form-control" name="desc" id="desc">{$ex->statement|escape}</textarea>
@ -85,7 +89,7 @@
<p>
<ul>
{foreach from=$theme->get_exercices_ordered() item=ex}
<li><a href="/{$SALT_ADMIN}/ex/{$theme->id}-{$theme->name}/{$ex->id}">{$ex->get_name()}</a></li>
<li><a href="/{$SALT_ADMIN}/ex/{$theme->id}-{$theme->name}/{$ex->id}">{$ex->get_title()}</a></li>
{/foreach}
</ul>
</p>

View File

@ -4,7 +4,7 @@
{if $theme->get_exercices_ordered()}
{foreach from=$theme->get_exercices_ordered() item=e}
<exercice id="{$e->id}" level="{$e->level}"{if $e->require} depends="{$e->require}"{/if}>
<title>{$e->get_name()}</title>
<title>{$e->get_title()}</title>
<points>{$e->points}</points>
<statement>{$e->statement}</statement>
{if $e->keys}

View File

@ -1,29 +1,55 @@
{extends file="admin/layout.tpl"}
{block name=content}
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">Certificat racine</h3>
<div class="row">
<div class="col-md-6">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Certificat racine</h3>
</div>
<div class="panel-body">
{if isset($cert_CA)}
<ul>
{foreach from=$cert_CA.subject key=k item=crt}
<li><strong>[{$k}] :</strong> {$crt}</li>
{/foreach}
</ul>
<a href="/{$SALT_ADMIN}/certificate/deleteca" class="btn btn-danger"
onclick="return confirm('Êtes-vous sûr de vouloir supprimer ce certificat ?')">Supprimer</a>
{elseif empty($cert_writable)}
<div class="alert alert-danger"><span class="glyphicon glyphicon-warning-sign"></span> Répertoire non accessible en écriture.</div>
<a href="/{$SALT_ADMIN}/certificate/newca" class="btn btn-primary" disabled="disabled">Nouveau</a>
{else}
Pas de certificat
<a href="/{$SALT_ADMIN}/certificate/newca" class="btn btn-primary">Nouveau</a>
{/if}
</div>
</div>
</div>
<div class="panel-body">
{if isset($cert)}
<ul>
<li><strong>[C] :</strong> {$cert['subject']['C']}</li>
<li><strong>[ST] :</strong> {$cert['subject']['ST']}</li>
<li><strong>[O] :</strong> {$cert['subject']['O']}</li>
<li><strong>[OU] :</strong> {$cert['subject']['OU']}</li>
<li><strong>[CN] :</strong> {$cert['subject']['CN']}</li>
<li><strong>[emailAddress] :</strong> {$cert['subject']['emailAddress']}</li>
</ul>
<!--<a href="/{$SALT_ADMIN}/certificate/deleteca" class="btn btn-danger"
onclick="return confirm('Êtes-vous sûr de vouloir supprimer ce certificat ?')">Supprimer</a>-->
{elseif isset($cert_writable) && ! $cert_writable}
<div class="alert alert-danger"><span class="glyphicon glyphicon-warning-sign"></span> Répertoire non accessible en écriture.</div>
<!--<a href="/{$SALT_ADMIN}/certificate/newca" class="btn btn-primary" disabled="disabled">Nouveau</a>-->
{else}
Pas de certificat
<!--<a href="/{$SALT_ADMIN}/certificate/newca" class="btn btn-primary">Nouveau</a>-->
{/if}
<div class="col-md-6">
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">Certificat serveur</h3>
</div>
<div class="panel-body">
{if isset($cert_srv)}
<ul>
{foreach from=$cert_srv.subject key=k item=crt}
<li><strong>[{$k}] :</strong> {$crt}</li>
{/foreach}
</ul>
<a href="/{$SALT_ADMIN}/certificate/revokesrv" class="btn btn-danger"
onclick="return confirm('Êtes-vous sûr de vouloir supprimer ce certificat ?')">Supprimer</a>
{elseif empty($cert_writable)}
<div class="alert alert-danger"><span class="glyphicon glyphicon-warning-sign"></span> Répertoire non accessible en écriture.</div>
<a href="/{$SALT_ADMIN}/certificate/newsrv" class="btn btn-primary" disabled="disabled">Nouveau</a>
{else}
Pas de certificat
<a href="/{$SALT_ADMIN}/certificate/newsrv" class="btn btn-primary">Nouveau</a>
{/if}
</div>
</div>
</div>
</div>
@ -36,7 +62,7 @@
<div class="form-group">
<label class="sr-only" for="time">Temps :</label>
<div class="input-group">
<input type="input" class="form-control" id="time" name="time" value="240">
<input type="input" class="form-control" id="time" name="time" value="{$DEF_TIME|default:240}">
<span class="input-group-addon">minutes</span>
</div>
</div>
@ -47,4 +73,90 @@
</form>
</div>
</div>
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">Génération</h3>
</div>
<div class="panel-body container">
<div class="col-xs-4">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>File d'attente</th>
</tr>
</thead>
<tbody id="genst">
<tr>
<td>Pending...</td>
</tr>
</tbody>
</table>
</div>
<pre class="col-xs-4" id="logs"></pre>
<div class="col-xs-4">
<a href="/{$SALT_ADMIN}/generation/full" onclick="call_gen('full'); return false" class="btn btn-default">Complet</a>
<a href="/{$SALT_ADMIN}/generation/home" onclick="call_gen('home'); return false" class="btn btn-default">Accueil</a>
<a href="/{$SALT_ADMIN}/generation/errors" onclick="call_gen('errors'); return false" class="btn btn-danger">Pages d'erreurs</a><br><br>
<a href="/{$SALT_ADMIN}/generation/sync" onclick="call_gen('sync'); return false" class="btn btn-info">Synchro légère</a>
<a href="/{$SALT_ADMIN}/generation/clear" onclick="call_gen('clear'); return false" class="btn btn-warning">Vider la file d'attente</a><br><br>
<a href="/{$SALT_ADMIN}/generation/freeze" onclick="call_gen('freeze'); return false" class="btn btn-danger">Freeze</a>
<a href="/{$SALT_ADMIN}/generation/unfreeze" onclick="call_gen('unfreeze'); return false" class="btn btn-success">Unfreeze</a><br><br>
<form method="post" action="/{$SALT_ADMIN}/generation/team" onsubmit="call_gen('team'); return false" role="form" class="form-inline">
<div class="form-group">
<input type="input" class="form-control" id="regenteam" name="team" placeholder="Team to regen">
<button type="submit" class="btn btn-primary">Regénérer</button>
</div>
</form><br>
<form method="post" action="/{$SALT_ADMIN}/generation/custom" onsubmit="call_gen('custom'); return false" role="form" class="form-inline">
<div class="form-group">
<input type="input" class="form-control" id="cmds" name="cmds" placeholder="Custom commands, : separated">
<button type="submit" class="btn btn-warning">Envoyer</button>
</div>
</form>
</div>
</div>
</div>
{/block}
{block name=end2}
<script type="text/javascript">
function call_gen(which) {
if (which == "team") datas = { 'team': $('#regenteam').val() }
else if (which == "custom") datas = { 'cmds': $('#cmds').val() }
else datas = { }
$.ajax({
type: 'POST',
data: datas,
url: './generation/' + which,
success: function(data){
$('#logs').html($(data).find('logs').text());
},
error: function() {
$('#logs').html('Oops! an error occurs during command execution');
}
});
}
function refresh_state() {
$.ajax({
type: 'GET',
url: './generation',
success: function(data){
$('#genst').empty();
$(data).find('item').each(function(i){
if (i == 0 && $(this).text() == "empty!")
color = "warning";
else if (i == 0)
color = "success";
else
color = "";
$('#genst').append('<tr><td class="' + color + '">' + $(this).text() + '</td></tr>') })
},
error: function() {
$('#genst').html('<tr><td class="danger">Oops! an error occurs during status refresh</td></tr>');
}
});
};
setInterval(refresh_state, 1000);
</script>
{/block}

View File

@ -11,8 +11,12 @@
<button type="submit" class="btn btn-primary">Importer</button>
</form>
{if isset($pass)}
<h2>Pass</h2>
<pre>{$pass|escape}</pre>
{/if}
{if isset($output)}
<h2>Output</h2>
<pre>{$output}</pre>
<pre>{$output|escape}</pre>
{/if}
{/block}

View File

@ -9,13 +9,14 @@
{/block}
{block name=end}
<script src="/js/countdown.js"></script>
<script src="{$SALT_CDN}/js/countdown.js"></script>
<script type="text/javascript">
{if isset($END)}
var end_challenge = new Date({$END * 1000});
{/if}
update_end();
</script>
{block name=end2}{/block}
{/block}
{block name=body}
@ -39,7 +40,7 @@
{link href_prefix="/{$SALT_ADMIN}/" href="ex/{$t->get_id()}-{$t->get_name()}" class="dropdown-toggle" data-toggle="dropdown" label="{$t->get_name()} <b class=\"caret\"></b>"}
<ul class="dropdown-menu">
{foreach from=$t->get_exercices_ordered() item=e}
<li>{link href_prefix="/{$SALT_ADMIN}/" href="ex/{$t->get_id()}-{$t->get_name()}/{$e->get_id()}" label="{$e->get_name()}"}</li>
<li>{link href_prefix="/{$SALT_ADMIN}/" href="ex/{$t->get_id()}-{$t->get_name()}/{$e->get_id()}" label="{$e->get_title(true)}"}</li>
{/foreach}
</ul>
</li>

View File

@ -22,7 +22,7 @@
<td><a href="/{$SALT_ADMIN}/ex/{$t->id}-{$t->name}">{$t->name}</a></td>
<td><ul>
{foreach from=$t->get_exercices_ordered() item=e}
<li><a href="/{$SALT_ADMIN}/ex/{$t->id}-{$t->name}/{$e->id}">{$e->get_name()}</a></li>
<li><a href="/{$SALT_ADMIN}/ex/{$t->id}-{$t->name}/{$e->id}">{$e->get_title()}</a></li>
{/foreach}
</ul></td>
<td>

View File

@ -23,7 +23,7 @@
<span class="glyphicon glyphicon-trash"></span></a>
<a href="/{$SALT_ADMIN}/certificate/get?name={$t->team_name}">
<span class="glyphicon glyphicon-floppy-save"></span></a>
{if not $t->revoked}
{if not $t->revoked && is_file("{$MISC_DIR}/PKI/pkcs/{$t->team_name}.p12")}
<a href="/{$SALT_ADMIN}/certificate/revoke?name={$t->team_name}"
onclick="return confirm('Êtes-vous sûr de vouloir révoquer ce certificat ?')">
<span class="glyphicon glyphicon-remove"></span></a>

View File

@ -1,18 +1,14 @@
<div class="clock">
<div id="ficlogo">
<a href="{$SALT_PUBLIC}/">
<img src="{$SALT_CDN}/img/challenge.jpg" alt="Forum International de la Cybersécurité">
<a href="{$SALT_PUBLIC}.">
<img src="{$SALT_CDN}img/challenge.jpg" alt="Forum International de la Cybersécurité">
</a>
</div>
<div id="epitalogo">
<img src="{$SALT_CDN}/img/epita.png" alt="Epita">
<img src="{$SALT_CDN}img/epita.png" alt="Epita">
</div>
<div id="Date"></div>
<ul>
<li id="hours"></li>
<li class="point">:</li>
<li id="min"></li>
<li class="point">:</li>
<li id="sec"></li>
<li>Challenge forensic</li>
</ul>
</div>

View File

@ -4,8 +4,9 @@
<meta charset="utf-8">
<title>{block name=title}Challenge FIC2014{/block}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="{$SALT_CDN}/css/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="{$SALT_CDN}/css/bootstrap-theme.min.css" rel="stylesheet" media="screen">
<base href="/">
<link href="{$SALT_CDN}css/bootstrap.min.css" rel="stylesheet" media="screen">
<link href="{$SALT_CDN}css/bootstrap-theme.min.css" rel="stylesheet" media="screen">
<!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!--[if lt IE 9]>
@ -13,7 +14,7 @@
<script src="../../assets/js/respond.min.js"></script>
<![endif]-->
<link rel="shortcut icon" type="image/x-icon" href="{$SALT_CDN}/favicon.ico">
<link rel="shortcut icon" type="image/x-icon" href="{$SALT_CDN}favicon.ico">
<meta name="author" content="EPITA Laboratoire SRS">
<meta name="robots" content="all">
<meta name="language" content="{$smarty.const.LANG}">
@ -40,8 +41,8 @@
</footer>
</div>
-->
<script src="{$SALT_CDN}/js/jquery.min.js"></script>
<script src="/js/bootstrap.min.js"></script>
<script src="{$SALT_CDN}js/jquery.min.js"></script>
<script src="js/bootstrap.min.js"></script>
{block name=end}{/block}
</body>
</html>

View File

@ -1,8 +1,7 @@
{extends file="layout.tpl"}
{block name=head}
<link href="/css/home.css" rel="stylesheet">
<link href="/css/score.css" rel="stylesheet">
<link href="{$SALT_CDN}css/main.css" type="text/css" rel="stylesheet">
{block name=head2}{/block}
{/block}
@ -40,7 +39,7 @@
{/block}
{block name=end}
<script src="/js/countdown.js"></script>
<script src="{$SALT_CDN}/js/countdown.js"></script>
<script type="text/javascript">
{if isset($END)}
var end_challenge = new Date({$END * 1000});

View File

@ -32,7 +32,7 @@
{if file_exists($file['path'])}
<tr>
<td>
<a href="/files/{$file['path_hash']}">
<a href="files/{$file['path_hash']}">
<span class="glyphicon glyphicon-download"></span>
</a>
</td>
@ -49,10 +49,18 @@
<div class="panel panel-success">
<div class="panel-heading">
<h3 class="panel-title">Soumettre une solution</h3>
<h3 class="panel-title">{if $my_team->id}Soumettre une solution{else}Solutions{/if}</h3>
</div>
<div class="panel-body">
{if $cur_exercice->has_solved($my_team)}
{if empty($my_team->id)}
Vérifiez votre solution parmi les algorithmes suivants :<br><br>
<dl class="dl-horizontal">
{foreach from=$cur_exercice->keys item=key}
<dt>{$key.format}</dt>
<dd><samp>{$key.value}</samp></dd>
{/foreach}
</dl>
{else if $cur_exercice->has_solved($my_team)}
<strong>R&eacute;solu &agrave; {$cur_exercice->has_solved($my_team)|date_format:"%H:%M:%S"} :)</strong>
{else}
{if $cur_exercice->last_try($my_team)}

View File

@ -1,18 +1,8 @@
{extends file="layout.tpl"}
{block name=head}
<link href="/css/home.css" rel="stylesheet">
<link href="/css/score.css" rel="stylesheet">
{/block}
{block name=end}
<script src="/js/countdown.js"></script>
<script type="text/javascript">
{if isset($END)}
var end_challenge = new Date({$END * 1000});
{/if}
update_end();
</script>
<link href="css/home.css" rel="stylesheet">
<link href="css/score.css" rel="stylesheet">
{/block}
{block name=body}
@ -28,23 +18,10 @@
<div class="row">
<div class="col-md-2">
<aside class="panel panel-default">
<div class="panel-body">
<p>
<span style="font-weight: bolder;">{$my_team->get_name()}{link class="badge pull-right" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="me" label="Info"}</span>
<em>{$my_team->get_slogan()}</em>
</p>
<p>
{$my_team->get_pts()} points{link class="badge pull-right" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="summary" label="Synthèse"}<br>
{$my_team->get_rank()}<sup>e</sup> sur {Team::get_nb_teams()}{link class="badge pull-right" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="rank" label="D&eacute;tails"}
</p>
</div>
</aside>
<div class="list-group">
{foreach from=$themes item=t key=k}
<a class="list-group-item" href="{link notag=1 href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$t->get_id()}-{$t->get_name_url()}/"}">
<span class="badge">{$my_team->get_nb_res_exercises_by_theme($t->get_id())}/{$t->get_nb_exercices()}</span>
<a class="list-group-item" href="{link notag=1 href_prefix="{$SALT_USER}/{intval($my_team->get_id())}/" href="{$t->get_id()}-{$t->get_name_url()}/"}">
<span class="badge">{$t->get_nb_exercices()}</span>
{$t->get_name()}
</a>
{/foreach}

View File

@ -4,7 +4,7 @@
<h3>Choisissez la team que vous voulez représenter :</h3>
{foreach from=$teams item=i}
<ul>
<li>{link href_prefix="/{$SALT_USER}/{$i->id}/" href="" label="{$i->team_name}"}</li>
<li>{link href_prefix="{$SALT_USER}/{$i->id}/" href="" label="{$i->team_name}"}</li>
</ul>
{/foreach}
</div>

View File

@ -1,14 +1,13 @@
{extends file="layout.tpl"}
{block name=head}
<link href="/css/home.css" rel="stylesheet">
<link href="/css/score.css" rel="stylesheet">
<link href="{$SALT_CDN}css/main.css" type="text/css" rel="stylesheet">
<meta http-equiv="refresh" content="30">
{block name=head2}{/block}
{/block}
{block name=end}
<script src="/js/countdown.js"></script>
<script src="{$SALT_CDN}js/countdown.js"></script>
<script type="text/javascript">
update_end();
</script>

View File

@ -1,24 +1,5 @@
{extends file="teams/layout.tpl"}
{block name=content}
<table class="table table-striped table-hover">
<thead>
<tr>
<th>#</th>
<th>Team</th>
<th>Slogan</th>
<th>Points</th>
</tr>
</thead>
<tbody>
{foreach from=$rank item=t key=k}
<tr{if $t->id == $my_team->id} class="active" style="font-weight: bold"{/if}>
<th>{$t->get_rank()}</th>
<td>{$t->get_name()}</td>
<td>{$t->slogan}</td>
<td>{$t->get_pts()}</td>
</tr>
{/foreach}
</tbody>
</table>
{include file="rank.tpl"}
{/block}

View File

@ -1,6 +1,18 @@
{extends file="teams/layout.tpl"}
{block name=content}
{if empty($my_team->id)}
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">Challenge forensic Épita 2015</h3>
</div>
<div class="panel-body">
Le challenge s'est déroulé le mardi 20 janvier 2015 lors du <a href="https://www.forum-fic.com/2015/">Forum International de la Cybercriminalité</a>. Bravo à tous les participants !<br><br>
Consultez la <a href="https://www.youtube.com/user/EpitaOfficiel">chaîne YouTube d'Épita</a> pour visionner les vidéos de résolutions des exercices.
</div>
</div>
{include file="rank.tpl"}
{else}
{if isset($percent)}
<div class="panel panel-default">
<div class="panel-heading">
@ -17,4 +29,5 @@
</div>
{/if}
{include file="summary.tpl"}
{/if}
{/block}

View File

@ -5,12 +5,14 @@
<h3 style="font-variant: small-caps">{$cur_theme->get_name()}</h3>
<p>
{foreach from=$cur_theme->get_exercices_ordered() item=exercice}
{if $exercice->has_solved($my_team)}
{link class="btn btn-success" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}" label="{$exercice->get_name()}"}
{if empty($my_team->id)}
{link class="btn btn-primary" role="button" href_prefix="{$SALT_USER}/{intval($my_team->get_id())}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}/" label="{$exercice->get_name()}"}
{elseif $exercice->has_solved($my_team)}
{link class="btn btn-success" role="button" href_prefix="{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}/" label="{$exercice->get_title(true)}"}
{elseif $exercice->is_unlocked($my_team)}
{link class="btn btn-primary" role="button" href_prefix="/{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}" label="{$exercice->get_name()}"}
{link class="btn btn-primary" role="button" href_prefix="{$SALT_USER}/{$my_team->get_id()}/" href="{$cur_theme->get_id()}-{$cur_theme->get_name_url()}/{$exercice->get_id()}/" label="{$exercice->get_title(true)}"}
{else}
<a class="btn btn-danger" disabled="disabled">{$exercice->get_name()}</a>
<a class="btn btn-danger" disabled="disabled">{$exercice->get_title(true)}</a>
{/if}
{/foreach}
</p>