fix perms + twig strict mode

This commit is contained in:
flash 2016-11-04 17:45:53 +01:00
parent 83632168d4
commit 93e96334a6
17 changed files with 93 additions and 45 deletions

View file

@ -16,24 +16,46 @@ use Sakura\User;
*/ */
class ForumPerms class ForumPerms
{ {
private static $table = 'forum_perms';
private $forums = []; private $forums = [];
private $user = 0; private $user = 0;
private $ranks = []; private $ranks = [];
private $cache = []; private $permCache = [];
private $validCache = [];
public function __construct(Forum $forum, User $user) public function __construct(Forum $forum, User $user)
{ {
$this->forums = [0, $forum->id, $forum->category]; $this->forums = [0, $forum->id, $forum->category]; // make this inherit everything before release
$this->user = $user->id; $this->user = $user->id;
$this->ranks = array_keys($user->ranks); $this->ranks = array_keys($user->ranks);
} }
public function __get($name) public function __get($name)
{ {
if (!array_key_exists($name, $this->cache)) { return $this->check($name);
}
public function __isset($name)
{
return $this->valid($name);
}
public function valid($name)
{
if (!array_key_exists($name, $this->validCache)) {
$column = 'perm_' . camel_to_snake($name);
$this->validCache[$name] = DB::getSchemaBuilder()->hasColumn(static::$table, $column);
}
return $this->validCache[$name];
}
public function check($name)
{
if (!array_key_exists($name, $this->permCache)) {
$column = 'perm_' . camel_to_snake($name); $column = 'perm_' . camel_to_snake($name);
$result = array_column(DB::table('forum_perms') $result = array_column(DB::table(static::$table)
->whereIn('forum_id', $this->forums) ->whereIn('forum_id', $this->forums)
->where(function ($query) { ->where(function ($query) {
$query->whereIn('rank_id', $this->ranks) $query->whereIn('rank_id', $this->ranks)
@ -41,9 +63,9 @@ class ForumPerms
}) })
->get([$column]), $column); ->get([$column]), $column);
$this->cache[$name] = !in_array('0', $result, true) && in_array('1', $result, true); $this->permCache[$name] = !in_array('0', $result, true) && in_array('1', $result, true);
} }
return $this->cache[$name]; return $this->permCache[$name];
} }
} }

View file

@ -106,6 +106,7 @@ class Template
: false, : false,
'auto_reload' => true, 'auto_reload' => true,
'debug' => config("dev.twig_debug"), 'debug' => config("dev.twig_debug"),
'strict_variables' => true,
]; ];
// And now actually initialise the templating engine // And now actually initialise the templating engine

View file

@ -13,9 +13,11 @@ namespace Sakura;
*/ */
class UserPerms class UserPerms
{ {
private static $table = 'perms';
private $user = 0; private $user = 0;
private $ranks = []; private $ranks = [];
private $cache = []; private $permCache = [];
private $validCache = [];
public function __construct(User $user) public function __construct(User $user)
{ {
@ -25,19 +27,39 @@ class UserPerms
public function __get($name) public function __get($name)
{ {
if (!array_key_exists($name, $this->cache)) { return $this->check($name);
}
public function __isset($name)
{
return $this->valid($name);
}
public function valid($name)
{
if (!array_key_exists($name, $this->validCache)) {
$column = 'perm_' . camel_to_snake($name);
$this->validCache[$name] = DB::getSchemaBuilder()->hasColumn(static::$table, $column);
}
return $this->validCache[$name];
}
public function check($name)
{
if (!array_key_exists($name, $this->permCache)) {
$column = 'perm_' . camel_to_snake($name); $column = 'perm_' . camel_to_snake($name);
$result = array_column(DB::table('perms') $result = array_column(DB::table(static::$table)
->where(function ($query) { ->where(function ($query) {
$query->whereIn('rank_id', $this->ranks) $query->whereIn('rank_id', $this->ranks)
->orWhere('user_id', $this->user); ->orWhere('user_id', $this->user);
}) })
->get([$column]), $column); ->get([$column]), $column);
$this->cache[$name] = !in_array('0', $result, true) && in_array('1', $result, true); $this->permCache[$name] = !in_array('0', $result, true) && in_array('1', $result, true);
} }
return $this->cache[$name]; return $this->permCache[$name];
} }
} }

View file

@ -25,7 +25,7 @@
</head> </head>
<body> <body>
<div class="container"> <div class="container">
<div class="container__wrapper {{ wrapper_classes or '' }}"> <div class="container__wrapper {{ wrapper_classes|default('') }}">
<nav class="header"> <nav class="header">
<div class="header__navigation"> <div class="header__navigation">
<a class="header__entry fa-home" href="{{ route('main.index') }}">home</a> <a class="header__entry fa-home" href="{{ route('main.index') }}">home</a>

View file

@ -129,9 +129,9 @@
<div class="platform profile__platform profile__accounts">{# <div class="platform profile__platform profile__accounts">{#
#}{% for id, data in fields %}{# #}{% for id, data in fields %}{#
#}{% if data.value != null %} #}{% if data.value != null %}
<a class="profile__account profile__account--{{ id }}"{% if data.link %} href="{{ data.link|format(data.value) }}"{% endif %}> <a class="profile__account profile__account--{{ id }}"{% if data.link is defined %} href="{{ data.link|format(data.value) }}"{% endif %}>
<div class="profile__account-icon fa-fw {{ data.icon }}"></div> <div class="profile__account-icon fa-fw {{ data.icon }}"></div>
<div class="profile__account-text">{{ (data.disp ? data.disp : '%s')|format(data.value) }}</div> <div class="profile__account-text">{{ (data.disp is defined ? data.disp : '%s')|format(data.value) }}</div>
</a> </a>
{% endif %}{# {% endif %}{#
#}{% endfor %}{# #}{% endfor %}{#

View file

@ -1,7 +1,6 @@
<div class="head">{{ title }}</div> <div class="head">{{ title }}</div>
<div class="forumList"> <div class="forumList">
{% for forum in forum.forums %} {% for forum in forum.forums %}
{{ forum.perms.view ? 'yay' : 'no'}}
{% if forum.type == 1 %} {% if forum.type == 1 %}
{% if forum.forums|length and forum.perms.view %} {% if forum.forums|length and forum.perms.view %}
<div class="forumCategory"> <div class="forumCategory">

View file

@ -2,19 +2,19 @@
<div class="buttonRow pagination"> <div class="buttonRow pagination">
<div class="leftSide"> <div class="leftSide">
{% if forumBackLink %} {% if forumBackLink is defined %}
<a href="{{ forumBackLink }}" class="forumbtn"><span class="fa fa-backward"></span> Back</a> <a href="{{ forumBackLink }}" class="forumbtn"><span class="fa fa-backward"></span> Back</a>
{% endif %} {% endif %}
{% if forumReplyLink %} {% if forumReplyLink is defined %}
<a href="{{ forumReplyLink }}" class="forumbtn"><span class="fa fa-reply-all"></span> Reply</a> <a href="{{ forumReplyLink }}" class="forumbtn"><span class="fa fa-reply-all"></span> Reply</a>
{% endif %} {% endif %}
{% if forumNewLink %} {% if forumNewLink is defined %}
<a href="{{ forumNewLink }}" class="forumbtn"><span class="fa fa-pencil-square-o"></span> New Topic</a> <a href="{{ forumNewLink }}" class="forumbtn"><span class="fa fa-pencil-square-o"></span> New Topic</a>
{% endif %} {% endif %}
{% if forumMarkRead %} {% if forumMarkRead is defined %}
<a href="{{ forumMarkRead }}" class="forumbtn"><span class="fa fa-check-square-o"></span> Mark as Read</a> <a href="{{ forumMarkRead }}" class="forumbtn"><span class="fa fa-check-square-o"></span> Mark as Read</a>
{% endif %} {% endif %}
{% if topic.id and showMod %} {% if topic.id is defined and showMod is defined %}
{% include 'forum/elements/forumMod.twig' %} {% include 'forum/elements/forumMod.twig' %}
{% endif %} {% endif %}
</div> </div>

View file

@ -24,7 +24,7 @@
<div> <div>
{% if forum.lastPost.id %} {% if forum.lastPost.id %}
<a href="{{ route('forums.topic', forum.lastPost.topic) }}" class="default">{{ forum.lastPost.subject|slice(0, 30) }}{% if forum.lastPost.subject|length > 30 %}...{% endif %}</a><br> <a href="{{ route('forums.topic', forum.lastPost.topic) }}" class="default">{{ forum.lastPost.subject|slice(0, 30) }}{% if forum.lastPost.subject|length > 30 %}...{% endif %}</a><br>
<time class="time-ago" datetime="{{ forum.lastPost.time|date('r') }}">{{ forum.lastPost.time|date(config('general.date_format')) }}</time> by {% if forum.lastPost.poster.id %}<a href="{{ route('user.profile', forum.lastPost.poster.id) }}" class="default" style="color: {{ forum.lastPost.poster.colour }}; text-shadow: 0 0 5px {% if forumlastPost.poster.colour != 'inherit' %}{{ forum.lastPost.poster.colour }}{% else %}#222{% endif %};">{{ forum.lastPost.poster.username }}</a>{% else %}[deleted user]{% endif %} <a href="{{ route('forums.post', forum.lastPost.id) }}" class="default fa fa-tag"></a> <time class="time-ago" datetime="{{ forum.lastPost.time|date('r') }}">{{ forum.lastPost.time|date(config('general.date_format')) }}</time> by {% if forum.lastPost.poster.id %}<a href="{{ route('user.profile', forum.lastPost.poster.id) }}" class="default" style="color: {{ forum.lastPost.poster.colour }}; text-shadow: 0 0 5px {% if forum.lastPost.poster.colour != 'inherit' %}{{ forum.lastPost.poster.colour }}{% else %}#222{% endif %};">{{ forum.lastPost.poster.username }}</a>{% else %}[deleted user]{% endif %} <a href="{{ route('forums.post', forum.lastPost.id) }}" class="default fa fa-tag"></a>
{% else %} {% else %}
There are no posts in this forum.<br>&nbsp; There are no posts in this forum.<br>&nbsp;
{% endif %} {% endif %}

View file

@ -11,5 +11,5 @@
<a class="forumbtn" title="Restore" href="{{ route('forums.topic.restore', topic.id) }}?session={{ session_id() }}"><span class="fa fa-history"></span></a> <a class="forumbtn" title="Restore" href="{{ route('forums.topic.restore', topic.id) }}?session={{ session_id() }}"><span class="fa fa-history"></span></a>
{% endif %} {% endif %}
{% if forumTrash is defined or forumPrune is defined %} {% if forumTrash is defined or forumPrune is defined %}
<a class="forumbtn" title="{{ forumPrune ? 'Prune' : 'Trash' }}" href="{{ route('forums.topic.delete', topic.id) }}?session={{ session_id() }}"><span class="fa fa-{{ forumPrune ? 'bomb' : 'trash' }}"></span></a> <a class="forumbtn" title="{{ forumPrune is defined ? 'Prune' : 'Trash' }}" href="{{ route('forums.topic.delete', topic.id) }}?session={{ session_id() }}"><span class="fa fa-{{ forumPrune is defined ? 'bomb' : 'trash' }}"></span></a>
{% endif %} {% endif %}

View file

@ -24,7 +24,7 @@
<div class="posting-buttons"> <div class="posting-buttons">
<div style="float: left;"> <div style="float: left;">
{% for code,meta in bbcode %} {% for code,meta in bbcode %}
<button onclick="Sakura.Editor.InsertBBCode(Sakura.DOM.ID('postingText'), '{{ code }}'{% if meta[2] %}, true{% endif %});" type="button"{% if meta[0] %} title="{{ meta[0] }}"{% endif %} class="forumbtn{% if meta[1] %} fa fa-{{ meta[1] }}{% endif %}">{% if not meta[1] %}{{ code }}{% endif %}</button> <button onclick="Sakura.Editor.InsertBBCode(Sakura.DOM.ID('postingText'), '{{ code }}'{% if meta[2] is defined %}, true{% endif %});" type="button"{% if meta[0] %} title="{{ meta[0] }}"{% endif %} class="forumbtn{% if meta[1] %} fa fa-{{ meta[1] }}{% endif %}">{% if not meta[1] %}{{ code }}{% endif %}</button>
{% endfor %} {% endfor %}
</div> </div>
<div style="float: right;"> <div style="float: right;">

View file

@ -96,7 +96,7 @@
{% include 'forum/elements/forumBtns.twig' %} {% include 'forum/elements/forumBtns.twig' %}
<table class="posts"> <table class="posts">
{% if topic is defined %} {% if topic is defined %}
{% set textCache = session.replyText['t' ~ topic.id] %} {% set textCache = session.replyText['t' ~ topic.id]|default(null) %}
{% set postingAction = route('forums.topic.reply', topic.id) %} {% set postingAction = route('forums.topic.reply', topic.id) %}
{% for post in posts[get.page|default(1) - 1] %} {% for post in posts[get.page|default(1) - 1] %}

View file

@ -7,8 +7,8 @@
<div> <div>
<h1>Information</h1> <h1>Information</h1>
<hr class="default"> <hr class="default">
{{ message }} {{ message|default('') }}
{% if redirect %}<br><a href="{{ redirect }}" class="default">Click here if you aren't being redirected.</a>{% endif %} {% if redirect is defined %}<br><a href="{{ redirect }}" class="default">Click here if you aren't being redirected.</a>{% endif %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View file

@ -5,8 +5,8 @@
<title>{{ title|default(config('general.name')) }}</title> <title>{{ title|default(config('general.name')) }}</title>
<meta name="description" content="{{ description|default(config('general.description')) }}"> <meta name="description" content="{{ description|default(config('general.description')) }}">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
{% if redirect %} {% if redirect is defined %}
<meta http-equiv="refresh" content="{{ redirectTimeout ? redirectTimeout : '3' }}; URL={{ redirect }}"> <meta http-equiv="refresh" content="{{ redirectTimeout is defined ? redirectTimeout : '3' }}; URL={{ redirect }}">
{% endif %} {% endif %}
{{ block('meta') }} {{ block('meta') }}
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css"> <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css">
@ -62,7 +62,7 @@
<div id="contentwrapper"> <div id="contentwrapper">
<div id="notifications" class="alerts"></div> <div id="notifications" class="alerts"></div>
<div id="dialogues" class="dialogues"></div> <div id="dialogues" class="dialogues"></div>
{% if profile is defined ? profile.background : (user.perms.changeBackground and (user.backgroundSitewide or showBG) and user.background) %} {% if profile is defined ? profile.background : (user.perms.changeBackground and (user.backgroundSitewide or showBG|default(false)) and user.background) %}
<div id="userBackground" style="background-image: url('{{ route('user.background', (profile is defined ? profile : user).id) }}');"></div> <div id="userBackground" style="background-image: url('{{ route('user.background', (profile is defined ? profile : user).id) }}');"></div>
{% endif %} {% endif %}
{% if not user.isActive and server['REQUEST_URI'] != route('auth.login') %} {% if not user.isActive and server['REQUEST_URI'] != route('auth.login') %}
@ -148,7 +148,7 @@
Yuuno.Main.Startup(); Yuuno.Main.Startup();
{% if config('dev.show_changelog') and stats %} {% if config('dev.show_changelog') and stats is defined %}
Sakura.Changelog.Build(Sakura.DOM.ID('indexPanel')); Sakura.Changelog.Build(Sakura.DOM.ID('indexPanel'));
{% endif %} {% endif %}

View file

@ -7,6 +7,7 @@
<h1 class="stylised">Friends</h1> <h1 class="stylised">Friends</h1>
</div> </div>
<div class="profile-friends"> <div class="profile-friends">
{% if friends|length > 0 %}
{% for friend in friends[get.page|default(1) - 1] %} {% for friend in friends[get.page|default(1) - 1] %}
<div class="friend-container" id="friendslist-friend-{{ friend.id }}"> <div class="friend-container" id="friendslist-friend-{{ friend.id }}">
<a class="friends-list-data clean" href="{{ route('user.profile', friend.id) }}"> <a class="friends-list-data clean" href="{{ route('user.profile', friend.id) }}">
@ -16,6 +17,9 @@
</div> </div>
{% endfor %} {% endfor %}
<div class="clear"></div> <div class="clear"></div>
{% else %}
<h1 class="stylised" style="text-align: center; margin: 2em auto;">This user has no friends :(</h1>
{% endif %}
</div> </div>
{% if friends|length > 1 %} {% if friends|length > 1 %}
<div style="text-align: right;"> <div style="text-align: right;">

View file

@ -47,7 +47,7 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
<div class="content settings messages {% if showBG %}background-transparent{% endif %}"> <div class="content settings messages">
<div class="content-right content-column"> <div class="content-right content-column">
<div class="head"> <div class="head">
Navigation Navigation

View file

@ -1,7 +1,7 @@
{% extends 'master.twig' %} {% extends 'master.twig' %}
{% set sorts = ['boxes', 'rectangles', 'list'] %} {% set sorts = ['boxes', 'rectangles', 'list'] %}
{% set sort = get.sort in sorts ? get.sort : sorts[0] %} {% set sort = get is defined and get.sort is defined and get.sort in sorts ? get.sort : sorts[0] %}
{% set notfound = rank == 0 %} {% set notfound = rank == 0 %}
@ -33,14 +33,14 @@
<a class="dropDownDesc">Rank:</a> <a class="dropDownDesc">Rank:</a>
{% for r in ranks %} {% for r in ranks %}
{% if not r.hidden or (r.hidden and rank == r.id) %} {% if not r.hidden or (r.hidden and rank == r.id) %}
<a href="{{ route('members.rank', r.id) }}{{ server['QUERY_STRING'] ? '?' : '' }}{{ server['QUERY_STRING'] }}" style="color: {{ r.colour }};"{% if rank == r.id %} class="dropDownSelected"{% endif %}>{{ r.id == 0 ? 'Not found' : r.name(true) }}</a> <a href="{{ route('members.rank', r.id) }}{{ server['QUERY_STRING'] is defined ? '?' : '' }}{{ server['QUERY_STRING']|default('') }}" style="color: {{ r.colour }};"{% if rank == r.id %} class="dropDownSelected"{% endif %}>{{ r.id == 0 ? 'Not found' : r.name(true) }}</a>
{% endif %} {% endif %}
{% endfor %} {% endfor %}
</div> </div>
<div class="dropDownInner" style="float: left;"> <div class="dropDownInner" style="float: left;">
<a class="dropDownDesc">View:</a> <a class="dropDownDesc">View:</a>
{% for s in sorts %} {% for s in sorts %}
<a href="?{{ server['QUERY_STRING'] }}{{ server['QUERY_STRING'] ? '&' : '' }}sort={{ s }}"{% if s == sort %} class="dropDownSelected"{% endif %}>{{ s|capitalize }}</a> <a href="?{{ server['QUERY_STRING']|default('') }}{{ server['QUERY_STRING']|default('') ? '&' : '' }}sort={{ s }}"{% if s == sort %} class="dropDownSelected"{% endif %}>{{ s|capitalize }}</a>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>

View file

@ -272,10 +272,10 @@
{{ data.title }} {{ data.title }}
</td> </td>
<td style="text-align: right;"> <td style="text-align: right;">
{% if data.link %} {% if data.link is defined %}
<a href="{{ data.link|format(data.value) }}" class="default">{{ (data.disp ? data.disp : '%s')|format(data.value) }}</a> <a href="{{ data.link|format(data.value) }}" class="default">{{ (data.disp is defined ? data.disp : '%s')|format(data.value) }}</a>
{% else %} {% else %}
{{ (data.disp ? data.disp : '%s')|format(data.value) }} {{ (data.disp is defined ? data.disp : '%s')|format(data.value) }}
{% endif %} {% endif %}
</td> </td>
</tr> </tr>