Kaynağa Gözat

refactor admin pages (create /admin/security)

Yuki Takei 8 yıl önce
ebeveyn
işleme
c94f837e03

+ 0 - 0
lib/form/admin/sec.js → lib/form/admin/securitygeneral.js


+ 0 - 0
lib/form/admin/google.js → lib/form/admin/securitygoogle.js


+ 2 - 2
lib/form/index.js

@@ -12,11 +12,11 @@ module.exports = {
   },
   admin: {
     app: require('./admin/app'),
-    sec: require('./admin/sec'),
     mail: require('./admin/mail'),
     aws: require('./admin/aws'),
-    google: require('./admin/google'),
     plugin: require('./admin/plugin'),
+    securityGeneral: require('./admin/securitygeneral'),
+    securityGoogle: require('./admin/securitygoogle'),
     markdown: require('./admin/markdown'),
     customcss: require('./admin/customcss'),
     customscript: require('./admin/customscript'),

+ 20 - 1
lib/routes/admin.js

@@ -87,7 +87,15 @@ module.exports = function(crowi, app) {
   actions.app.settingUpdate = function(req, res) {
   };
 
-  // app.get('/admin/markdonw'                  , admin.markdonw.index);
+  // app.get('/admin/security'                  , admin.security.index);
+  actions.security = {};
+  actions.security.index = function(req, res) {
+    var settingForm;
+    settingForm = Config.setupCofigFormData('crowi', req.config);
+    return res.render('admin/security', { settingForm });
+  };
+
+  // app.get('/admin/markdown'                  , admin.markdown.index);
   actions.markdown = {};
   actions.markdown.index = function(req, res) {
     var config = crowi.getConfig();
@@ -497,6 +505,17 @@ module.exports = function(crowi, app) {
     }
   };
 
+  actions.api.securitySetting = function(req, res) {
+    var form = req.form.settingForm;
+
+    if (req.form.isValid) {
+      debug('form content', form);
+      return saveSetting(req, res, form);
+    } else {
+      return res.json({status: false, message: req.form.errors.join('\n')});
+    }
+  };
+
   actions.api.customizeSetting = function(req, res) {
     var form = req.form.settingForm;
 

+ 5 - 2
lib/routes/index.js

@@ -42,12 +42,15 @@ module.exports = function(crowi, app) {
   app.get('/admin'                      , loginRequired(crowi, app) , middleware.adminRequired() , admin.index);
   app.get('/admin/app'                  , loginRequired(crowi, app) , middleware.adminRequired() , admin.app.index);
   app.post('/_api/admin/settings/app'   , loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.app, admin.api.appSetting);
-  app.post('/_api/admin/settings/sec'   , loginRequired(crowi, app) , middleware.adminRequired() , form.admin.sec, admin.api.appSetting);
   app.post('/_api/admin/settings/mail'  , loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.mail, admin.api.appSetting);
   app.post('/_api/admin/settings/aws'   , loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.aws, admin.api.appSetting);
-  app.post('/_api/admin/settings/google', loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.google, admin.api.appSetting);
   app.post('/_api/admin/settings/plugin', loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.plugin, admin.api.appSetting);
 
+  // security admin
+  app.get('/admin/security'                     , loginRequired(crowi, app) , middleware.adminRequired() , admin.security.index);
+  app.post('/_api/admin/security/general'       , loginRequired(crowi, app) , middleware.adminRequired() , form.admin.securityGeneral, admin.api.securitySetting);
+  app.post('/_api/admin/security/google'        , loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.securityGoogle, admin.api.securitySetting);
+
   // markdown admin
   app.get('/admin/markdown'                   , loginRequired(crowi, app) , middleware.adminRequired() , admin.markdown.index);
   app.post('/admin/markdown/lineBreaksSetting', loginRequired(crowi, app) , middleware.adminRequired() , csrf, form.admin.markdown, admin.markdown.lineBreaksSetting);

+ 1 - 108
lib/views/admin/app.html

@@ -81,70 +81,6 @@
       </fieldset>
       </form>
 
-      <form action="/_api/admin/settings/sec" method="post" class="form-horizontal" id="secSettingForm" role="form">
-      <fieldset>
-      <legend>セキュリティ設定</legend>
-
-        <div class="form-group">
-          <label for="settingForm[security:registrationMode]" class="col-xs-3 control-label">Basic認証</label>
-          <div class="col-xs-3">
-            <label for="">ID</label>
-            <input class="form-control" type="text" name="settingForm[security:basicName]"   value="{{ settingForm['security:basicName']|default('') }}">
-          </div>
-          <div class="col-xs-3">
-            <label for="">パスワード</label>
-            <input class="form-control" type="text" name="settingForm[security:basicSecret]" value="{{ settingForm['security:basicSecret']|default('') }}">
-          </div>
-          <div class="col-xs-offset-3 col-xs-9">
-            <p class="help-block">
-              Basic認証を設定すると、ページ全体に共通の認証がかかります。<br>
-              IDとパスワードは暗号化されずに送信されるのでご注意下さい。<br>
-            </p>
-          </div>
-        </div>
-
-        <div class="form-group">
-          <label for="settingForm[security:restrictGuestMode]" class="col-xs-3 control-label">ゲストユーザーのアクセス</label>
-          <div class="col-xs-6">
-            <select class="form-control" name="settingForm[security:restrictGuestMode]" value="{{ settingForm['security:restrictGuestMode'] }}">
-              {% for modeValue, modeLabel in consts.restrictGuestMode %}
-              <option value="{{ modeValue }}" {% if modeValue == settingForm['security:restrictGuestMode'] %}selected{% endif %} >{{ modeLabel }}</option>
-              {% endfor %}
-            </select>
-          </div>
-        </div>
-
-        <div class="form-group">
-          <label for="settingForm[security:registrationMode]" class="col-xs-3 control-label">登録の制限</label>
-          <div class="col-xs-6">
-            <select class="form-control" name="settingForm[security:registrationMode]" value="{{ settingForm['security:registrationMode'] }}">
-              {% for modeValue, modeLabel in consts.registrationMode %}
-              <option value="{{ modeValue }}" {% if modeValue == settingForm['security:registrationMode'] %}selected{% endif %} >{{ modeLabel }}</option>
-              {% endfor %}
-            </select>
-            <p class="help-block">ここに入力した内容は、ヘッダー等に表示されます。</p>
-          </div>
-        </div>
-
-        <div class="form-group">
-          <label for="settingForm[security:registrationWhiteList]" class="col-xs-3 control-label">登録許可メールアドレスの<br>ホワイトリスト</label>
-          <div class="col-xs-8">
-            <textarea class="form-control" type="textarea" name="settingForm[security:registrationWhiteList]" placeholder="例: @crowi.wiki">{{ settingForm['security:registrationWhiteList']|join('&#13')|raw }}</textarea>
-            <p class="help-block">登録可能なメールアドレスを制限することができます。例えば、会社で使う場合、<code>@crowi.wiki</code> などと記載すると、その会社のメールアドレスを持っている人のみ登録可能になります。<br>
-            1行に1メールアドレス入力してください。</p>
-          </div>
-        </div>
-
-        <div class="form-group">
-          <div class="col-xs-offset-3 col-xs-6">
-            <input type="hidden" name="_csrf" value="{{ csrf() }}">
-            <button type="submit" class="btn btn-primary">更新</button>
-          </div>
-        </div>
-
-      </fieldset>
-      </form>
-
       <form action="/_api/admin/settings/mail" method="post" class="form-horizontal" id="mailSettingForm" role="form">
       <fieldset>
       <legend>メールの設定</legend>
@@ -239,49 +175,6 @@
       </fieldset>
       </form>
 
-      <form action="/_api/admin/settings/google" method="post" class="form-horizontal" id="googleSettingForm" role="form">
-      <fieldset>
-      <legend>Google 設定</legend>
-        <p class="well">
-          Google Cloud Platform の <a href="https://console.cloud.google.com/apis/credentials">API Manager</a>
-          から OAuth2 Client ID を作成すると、Google アカウントにコネクトして登録やログインが可能になります。
-        </p>
-
-        <ol class="help-block">
-          <li><a href="https://console.cloud.google.com/apis/credentials">API Manager</a> へアクセス</li>
-          <li>プロジェクトを作成していない場合は作成してください</li>
-          <li>「認証情報を作成」-> OAuthクライアントID</li>
-          <ol>
-            <li>「ウェブアプリケーション」を選択</li>
-            <li>承認済みのリダイレクトURLに、 <code>https://${crowi.host}/google/callback</code> を入力<br>
-            (<code>${crowi.host}</code>は環境に合わせて変更してください)</li>
-          </ol>
-        </ol>
-
-        <div class="form-group">
-          <label for="settingForm[google:clientId]" class="col-xs-3 control-label">Client ID</label>
-          <div class="col-xs-6">
-            <input class="form-control" type="text" name="settingForm[google:clientId]" value="{{ settingForm['google:clientId'] }}">
-          </div>
-        </div>
-
-        <div class="form-group">
-          <label for="settingForm[google:clientSecret]" class="col-xs-3 control-label">Client Secret</label>
-          <div class="col-xs-6">
-            <input class="form-control" type="text" name="settingForm[google:clientSecret]" value="{{ settingForm['google:clientSecret'] }}">
-          </div>
-        </div>
-
-        <div class="form-group">
-          <div class="col-xs-offset-3 col-xs-6">
-            <input type="hidden" name="_csrf" value="{{ csrf() }}">
-            <button type="submit" class="btn btn-primary">更新</button>
-          </div>
-        </div>
-
-      </fieldset>
-      </form>
-
       <form action="/_api/admin/settings/plugin" method="post" class="form-horizontal" id="pluginSettingForm" role="form">
       <fieldset>
       <legend>プラグイン設定</legend>
@@ -317,7 +210,7 @@
   </div>
 
   <script>
-    $('#appSettingForm, #secSettingForm, #mailSettingForm, #awsSettingForm, #googleSettingForm, #pluginSettingForm').each(function() {
+    $('#appSettingForm, #mailSettingForm, #awsSettingForm, #pluginSettingForm').each(function() {
       $(this).submit(function()
       {
         function showMessage(formId, msg, status) {

+ 203 - 0
lib/views/admin/security.html

@@ -0,0 +1,203 @@
+{% extends '../layout/admin.html' %}
+
+{% block html_title %}セキュリティ · {% endblock %}
+
+{% block content_head %}
+<div class="header-wrap">
+  <header id="page-header">
+    <h1 class="title" id="">カスタマイズ</h1>
+  </header>
+</div>
+{% endblock %}
+
+{% block content_main %}
+<div class="content-main">
+  <div class="row">
+    <div class="col-md-3">
+      {% include './widget/menu.html' with {current: 'notification'} %}
+    </div>
+    <div class="col-md-9">
+
+      {% set smessage = req.flash('successMessage') %}
+      {% if smessage.length %}
+      <div class="alert alert-success">
+        {% for e in smessage %}
+          {{ e }}<br>
+        {% endfor %}
+      </div>
+      {% endif %}
+
+      {% set emessage = req.flash('errorMessage') %}
+      {% if emessage.length %}
+      <div class="alert alert-danger">
+        {% for e in emessage %}
+        {{ e }}<br>
+        {% endfor %}
+      </div>
+      {% endif %}
+
+      <form action="/_api/admin/security/general" method="post" class="form-horizontal" id="generalSetting" role="form">
+        <fieldset>
+        <legend>セキュリティ設定</legend>
+
+          <div class="form-group">
+            <label for="settingForm[security:registrationMode]" class="col-xs-3 control-label">Basic認証</label>
+            <div class="col-xs-3">
+              <label for="">ID</label>
+              <input class="form-control" type="text" name="settingForm[security:basicName]"   value="{{ settingForm['security:basicName']|default('') }}">
+            </div>
+            <div class="col-xs-3">
+              <label for="">パスワード</label>
+              <input class="form-control" type="text" name="settingForm[security:basicSecret]" value="{{ settingForm['security:basicSecret']|default('') }}">
+            </div>
+            <div class="col-xs-offset-3 col-xs-9">
+              <p class="help-block">
+                Basic認証を設定すると、ページ全体に共通の認証がかかります。<br>
+                IDとパスワードは暗号化されずに送信されるのでご注意下さい。<br>
+              </p>
+            </div>
+          </div>
+
+          <div class="form-group">
+            <label for="settingForm[security:restrictGuestMode]" class="col-xs-3 control-label">ゲストユーザーのアクセス</label>
+            <div class="col-xs-6">
+              <select class="form-control" name="settingForm[security:restrictGuestMode]" value="{{ settingForm['security:restrictGuestMode'] }}">
+                {% for modeValue, modeLabel in consts.restrictGuestMode %}
+                <option value="{{ modeValue }}" {% if modeValue == settingForm['security:restrictGuestMode'] %}selected{% endif %} >{{ modeLabel }}</option>
+                {% endfor %}
+              </select>
+            </div>
+          </div>
+
+          <div class="form-group">
+            <label for="settingForm[security:registrationMode]" class="col-xs-3 control-label">登録の制限</label>
+            <div class="col-xs-6">
+              <select class="form-control" name="settingForm[security:registrationMode]" value="{{ settingForm['security:registrationMode'] }}">
+                {% for modeValue, modeLabel in consts.registrationMode %}
+                <option value="{{ modeValue }}" {% if modeValue == settingForm['security:registrationMode'] %}selected{% endif %} >{{ modeLabel }}</option>
+                {% endfor %}
+              </select>
+              <p class="help-block">ここに入力した内容は、ヘッダー等に表示されます。</p>
+            </div>
+          </div>
+
+          <div class="form-group">
+            <label for="settingForm[security:registrationWhiteList]" class="col-xs-3 control-label">登録許可メールアドレスの<br>ホワイトリスト</label>
+            <div class="col-xs-8">
+              <textarea class="form-control" type="textarea" name="settingForm[security:registrationWhiteList]" placeholder="例: @crowi.wiki">{{ settingForm['security:registrationWhiteList']|join('&#13')|raw }}</textarea>
+              <p class="help-block">登録可能なメールアドレスを制限することができます。例えば、会社で使う場合、<code>@crowi.wiki</code> などと記載すると、その会社のメールアドレスを持っている人のみ登録可能になります。<br>
+              1行に1メールアドレス入力してください。</p>
+            </div>
+          </div>
+
+          <div class="form-group">
+            <div class="col-xs-offset-3 col-xs-6">
+              <input type="hidden" name="_csrf" value="{{ csrf() }}">
+              <button type="submit" class="btn btn-primary">更新</button>
+            </div>
+          </div>
+
+        </fieldset>
+      </form>
+
+      <form action="/_api/admin/security/google" method="post" class="form-horizontal" id="googleSetting" role="form">
+        <fieldset>
+          <legend>Google 設定</legend>
+          <p class="well">
+            Google Cloud Platform の <a href="https://console.cloud.google.com/apis/credentials">API Manager</a>
+            から OAuth2 Client ID を作成すると、Google アカウントにコネクトして登録やログインが可能になります。
+          </p>
+
+          <ol class="help-block">
+            <li><a href="https://console.cloud.google.com/apis/credentials">API Manager</a> へアクセス</li>
+            <li>プロジェクトを作成していない場合は作成してください</li>
+            <li>「認証情報を作成」-> OAuthクライアントID</li>
+            <ol>
+              <li>「ウェブアプリケーション」を選択</li>
+              <li>承認済みのリダイレクトURLに、 <code>https://${crowi.host}/google/callback</code> を入力<br>
+              (<code>${crowi.host}</code>は環境に合わせて変更してください)</li>
+            </ol>
+          </ol>
+
+          <div class="form-group">
+            <label for="settingForm[google:clientId]" class="col-xs-3 control-label">Client ID</label>
+            <div class="col-xs-6">
+              <input class="form-control" type="text" name="settingForm[google:clientId]" value="{{ settingForm['google:clientId'] }}">
+            </div>
+          </div>
+
+          <div class="form-group">
+            <label for="settingForm[google:clientSecret]" class="col-xs-3 control-label">Client Secret</label>
+            <div class="col-xs-6">
+              <input class="form-control" type="text" name="settingForm[google:clientSecret]" value="{{ settingForm['google:clientSecret'] }}">
+            </div>
+          </div>
+
+          <div class="form-group">
+            <div class="col-xs-offset-3 col-xs-6">
+              <input type="hidden" name="_csrf" value="{{ csrf() }}">
+              <button type="submit" class="btn btn-primary">更新</button>
+            </div>
+          </div>
+
+        </fieldset>
+      </form>
+
+    </div>
+  </div>
+
+  <script>
+    $('#generalSetting, #googleSetting').each(function() {
+      $(this).submit(function()
+      {
+        function showMessage(formId, msg, status) {
+          $('#' + formId + ' .alert').remove();
+
+          if (!status) {
+            status = 'success';
+          }
+          var $message = $('<p class="alert"></p>');
+          $message.addClass('alert-' + status);
+          $message.html(msg.replace('\n', '<br>'));
+          $message.insertAfter('#' + formId + ' legend');
+
+          if (status == 'success') {
+            setTimeout(function()
+            {
+              $message.fadeOut({
+                complete: function() {
+                  $message.remove();
+                }
+              });
+            }, 5000);
+          }
+        }
+
+        var $form = $(this);
+        var $id = $form.attr('id');
+        var $button = $('button', this);
+        $button.attr('disabled', 'disabled');
+        var jqxhr = $.post($form.attr('action'), $form.serialize(), function(data)
+          {
+            if (data.status) {
+              showMessage($id, '更新しました');
+            } else {
+              showMessage($id, data.message, 'danger');
+            }
+          })
+          .fail(function() {
+            showMessage($id, 'エラーが発生しました', 'danger');
+          })
+          .always(function() {
+            $button.prop('disabled', false);
+        });
+        return false;
+      });
+    });
+
+  </script>
+</div>
+{% endblock content_main %}
+
+{% block content_footer %}
+{% endblock content_footer %}

+ 1 - 0
lib/views/admin/widget/menu.html

@@ -4,6 +4,7 @@
 <ul class="nav nav-pills nav-stacked">
   <li class="{% if current == 'index'%}active{% endif %}"><a href="/admin"><i class="fa fa-cube"></i> Wiki管理トップ</a></li>
   <li class="{% if current == 'app'%}active{% endif %}"><a href="/admin/app"><i class="fa fa-gears"></i> アプリ設定</a></li>
+  <li class="{% if current == 'security'%}active{% endif %}"><a href="/admin/security"><i class="fa fa-shield"></i> セキュリティ設定</a></li>
   <li class="{% if current == 'markdown'%}active{% endif %}"><a href="/admin/markdown"><i class="fa fa-pencil"></i> Markdown設定</a></li>
   <li class="{% if current == 'customize'%}active{% endif %}"><a href="/admin/customize"><i class="fa fa-object-group"></i> カスタマイズ</a></li>
   <li class="{% if current == 'notification'%}active{% endif %}"><a href="/admin/notification"><i class="fa fa-bell"></i> 通知設定</a></li>

+ 8 - 7
lib/views/layout/single.html

@@ -17,12 +17,13 @@
 {% endblock %} {# layout_main #}
 
 {% block footer %}
-<div id="footer-container" class="footer">
-  <footer class="">
-    <p>
-      <a href="" data-target="#help-modal" data-toggle="modal"><i class="fa fa-question-circle"></i> {{ t('Help') }}</a>
-      <a href="https://github.com/weseek/crowi-plus">crowi-plus</a> {{ crowiVersion() }}
-    </p>
-  </footer>
+{% parent %}
+<div class="system-version">
+  <span>
+    <a href="https://github.com/weseek/crowi-plus">crowi-plus</a> {{ crowiVersion() }}
+  </span>
+  <span>
+    <a href="" data-target="#help-modal" data-toggle="modal"><i class="fa fa-question-circle"></i> {{ t('Help') }}</a>
+  </span>
 </div>
 {% endblock %}