]> source.dussan.org Git - sonarqube.git/commitdiff
SSF-25 SMTP configuration password
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Mon, 22 Dec 2014 13:42:01 +0000 (14:42 +0100)
committerJulien Lancelot <julien.lancelot@sonarsource.com>
Mon, 22 Dec 2014 13:42:10 +0000 (14:42 +0100)
server/sonar-web/src/main/webapp/WEB-INF/app/controllers/email_configuration_controller.rb
server/sonar-web/src/main/webapp/WEB-INF/app/controllers/settings_controller.rb
server/sonar-web/src/main/webapp/WEB-INF/app/models/property.rb
server/sonar-web/src/main/webapp/WEB-INF/app/views/email_configuration/index.html.erb
server/sonar-web/src/main/webapp/WEB-INF/app/views/settings/_properties.html.erb
server/sonar-web/src/main/webapp/WEB-INF/app/views/settings/_set_instance.html.erb
server/sonar-web/src/main/webapp/WEB-INF/app/views/settings/_type_PASSWORD.html.erb
server/sonar-web/src/main/webapp/WEB-INF/app/views/settings/_update_password_form.html.erb [new file with mode: 0644]

index 33b8600e4c500dae2961c5725fa58b3dc15c86b7..9fb6c4d8f4bec274b5bc62cfceb9d4c8839cb84c 100644 (file)
@@ -23,27 +23,30 @@ class EmailConfigurationController < ApplicationController
   before_filter :admin_required
 
   def index
-  @smtp_host = Property.value(configuration::SMTP_HOST, nil, configuration::SMTP_HOST_DEFAULT)
-  @smtp_port = Property.value(configuration::SMTP_PORT, nil, configuration::SMTP_PORT_DEFAULT)
-  @smtp_secure_connection = Property.value(configuration::SMTP_SECURE_CONNECTION, nil, configuration::SMTP_SECURE_CONNECTION)
-  @smtp_username = Property.value(configuration::SMTP_USERNAME, nil, configuration::SMTP_USERNAME_DEFAULT)
-  @smtp_password = Property.value(configuration::SMTP_PASSWORD, nil, configuration::SMTP_PASSWORD_DEFAULT)
-  @email_from = Property.value(configuration::FROM, nil, configuration::FROM_DEFAULT)
-  @email_prefix = Property.value(configuration::PREFIX, nil, configuration::PREFIX_DEFAULT)
-  @server_base_url = Property.value(properties::SERVER_BASE_URL, nil, properties::SERVER_BASE_URL_DEFAULT_VALUE)
-  params[:layout]='false'
+    @smtp_host = Property.value(configuration::SMTP_HOST, nil, configuration::SMTP_HOST_DEFAULT)
+    @smtp_port = Property.value(configuration::SMTP_PORT, nil, configuration::SMTP_PORT_DEFAULT)
+    @smtp_secure_connection = Property.value(configuration::SMTP_SECURE_CONNECTION, nil, configuration::SMTP_SECURE_CONNECTION)
+    @smtp_username = Property.value(configuration::SMTP_USERNAME, nil, configuration::SMTP_USERNAME_DEFAULT)
+    @smtp_password = Property.value(configuration::SMTP_PASSWORD, nil, configuration::SMTP_PASSWORD_DEFAULT)
+    @email_from = Property.value(configuration::FROM, nil, configuration::FROM_DEFAULT)
+    @email_prefix = Property.value(configuration::PREFIX, nil, configuration::PREFIX_DEFAULT)
+    @server_base_url = Property.value(properties::SERVER_BASE_URL, nil, properties::SERVER_BASE_URL_DEFAULT_VALUE)
+    params[:layout]='false'
   end
 
   def save
-  Property.set(configuration::SMTP_HOST, params[:smtp_host])
-  Property.set(configuration::SMTP_PORT, params[:smtp_port])
-  Property.set(configuration::SMTP_SECURE_CONNECTION, params[:smtp_secure_connection])
-  Property.set(configuration::SMTP_USERNAME, params[:smtp_username])
-  Property.set(configuration::SMTP_PASSWORD, params[:smtp_password])
-  Property.set(configuration::FROM, params[:email_from])
-  Property.set(configuration::PREFIX, params[:email_prefix])
-  flash[:notice] = message('email_configuration.settings_saved')
-  redirect_to :action => 'index'
+    Property.set(configuration::SMTP_HOST, params[:smtp_host])
+    Property.set(configuration::SMTP_PORT, params[:smtp_port])
+    Property.set(configuration::SMTP_SECURE_CONNECTION, params[:smtp_secure_connection])
+    Property.set(configuration::SMTP_USERNAME, params[:smtp_username])
+    # Password can only be set when empty, the update will be done by the edit modal window
+    if !params[:smtp_password].blank?
+      Property.set(configuration::SMTP_PASSWORD, params[:smtp_password])
+    end
+    Property.set(configuration::FROM, params[:email_from])
+    Property.set(configuration::PREFIX, params[:email_prefix])
+    flash[:notice] = message('email_configuration.settings_saved')
+    redirect_to :action => 'index'
   end
 
   def send_test_email
@@ -66,7 +69,7 @@ class EmailConfigurationController < ApplicationController
   private
 
   def configuration
-  java_facade.getComponentByClassname('emailnotifications', 'org.sonar.api.config.EmailSettings').class
+    java_facade.getComponentByClassname('emailnotifications', 'org.sonar.api.config.EmailSettings').class
   end
 
   def properties
index 5a48b65955827d0bcf582b7eb52236dd6ceaab89..b687906388478135b29f800a27076fcf5b50b6e0 100644 (file)
@@ -44,6 +44,32 @@ class SettingsController < ApplicationController
     render :partial => 'settings/properties'
   end
 
+  def update_password_form
+    @key = params[:key]
+    @component_id = params[:component_id]
+    render :partial => 'settings/update_password_form'
+  end
+
+  def update_password
+    property_key = params[:key]
+    component_id = params[:component_id]
+    not_found('Property key should be set') unless property_key
+    component_id = !component_id.blank? ? component_id : nil
+    password = params[:password]
+
+    property = Property.by_key(property_key, component_id)
+    if property
+      if !password.blank?
+        property.text_value = password
+        property.save
+      else
+        property.delete
+      end
+    end
+    Property.setGlobalProperty(property_key, password, component_id, nil)
+    render :text => 'ok', :status => 200
+  end
+
   private
 
   def update_properties(resource_id)
@@ -63,7 +89,7 @@ class SettingsController < ApplicationController
       max = (Time.now.to_f * 100000).to_i
       set_keys.each_with_index do |v, index|
         if v.blank?
-          max += 1;
+          max += 1
           set_keys[index] = max.to_s
         end
       end
@@ -80,7 +106,15 @@ class SettingsController < ApplicationController
     set_keys.reject! { |set_key| set_key.blank? || (auto_generate && set_key_values[set_key].values.all?(&:blank?)) }
 
     Property.transaction do
-      Property.with_key_prefix(key + '.').with_resource(resource_id).delete_all
+      # Delete only property sets that are no more existing
+      condition = ''
+      set_keys.each {|set_key| condition += "prop_key NOT LIKE ('#{key + '.' + set_key + '.%'}') AND "}
+      if resource_id
+        condition += 'resource_id=' + resource_id
+      else
+        condition += 'resource_id IS NULL'
+      end
+      Property.delete_all(condition)
 
       update_property(key, set_keys, resource_id)
       set_keys.each do |set_key|
index 97744feb51cce92754ae5542d4937ae33a6b8e4f..1c96bbbfe25ce09f6fd5cfa734082f0bf1d2d43d 100644 (file)
@@ -94,7 +94,11 @@ class Property < ActiveRecord::Base
     text_value = value.to_s if defined? value
     text_value = nil if text_value.blank?
 
-    if text_value.blank?
+    # Load Java property definition
+    property_def = field_property_def(key) || property_def(key)
+
+    # Dot not delete password properties
+    if text_value.blank? && property_def.type().to_s != PropertyType::TYPE_PASSWORD
       return Property.clear(key, resource_id)
     end
 
@@ -103,8 +107,11 @@ class Property < ActiveRecord::Base
       return prop
     end
 
-    unless prop
+    if !prop
       prop = Property.new(:prop_key => key, :resource_id => resource_id, :user_id => user_id)
+    # Existing password should not be touched
+    elsif property_def.type().to_s == PropertyType::TYPE_PASSWORD && !prop.text_value.blank?
+      text_value = prop.text_value
     end
 
     prop.text_value = text_value
@@ -139,22 +146,11 @@ class Property < ActiveRecord::Base
   end
 
   def java_definition
-    @java_definition ||=
-      begin
-        Api::Utils.java_facade.propertyDefinitions.get(key)
-      end
+    @java_definition ||= Property.property_def(key)
   end
 
   def java_field_definition
-    @java_field_definition ||=
-      begin
-        if /(.*)\..*\.(.*)/.match(key)
-          property_definition = Api::Utils.java_facade.propertyDefinitions.get(Regexp.last_match(1))
-          if property_definition
-            property_definition.fields.find { |field| field.key == Regexp.last_match(2) }
-          end
-        end
-      end
+    @java_field_definition ||= Property.field_property_def(key)
   end
 
   def validation_error_message
@@ -173,12 +169,12 @@ class Property < ActiveRecord::Base
     array.map { |v| v.gsub(',', '%2C') }.join(',')
   end
 
-  private
-
   def self.setGlobalProperty(key, value, resource_id, user_id)
     Api::Utils.java_facade.setGlobalProperty(key, value) unless (resource_id || user_id)
   end
 
+  private
+
   def self.all(key, resource_id=nil, user_id=nil)
     Property.with_key(key).with_resource(resource_id).with_user(user_id)
   end
@@ -205,4 +201,22 @@ class Property < ActiveRecord::Base
       errors.add_to_base(validation_result.errorKey) unless validation_result.isValid()
     end
   end
+
+  def self.property_def(key)
+    begin
+      Api::Utils.java_facade.propertyDefinitions.get(key)
+    end
+  end
+
+  def self.field_property_def(key)
+    begin
+      if /(.*)\..*\.(.*)/.match(key)
+        property_definition = Api::Utils.java_facade.propertyDefinitions.get(Regexp.last_match(1))
+        if property_definition
+          property_definition.fields.find { |field| field.key == Regexp.last_match(2) }
+        end
+      end
+    end
+  end
+
 end
index bea86751e415b1b538d1cfe44aeb6ea048a11290..1e1f11bf2f40e45bb18fa359e49ca0085583a66f 100644 (file)
     <tr class="property">
       <th><label for="smtp_password"><h3><%= message('email_configuration.smtp_password') -%></h3></label></th>
       <td>
-        <%= password_field_tag 'smtp_password', @smtp_password, {:autocomplete => 'off'}  %>
+        <% if @smtp_password.blank? %>
+          <input type="password" name="smtp_password" id="smtp_password">
+        <% else %>
+          <span class="marginright10">**********</span>
+          <a id="update-smtp-password" href="<%=ApplicationController.root_context-%>/settings/update_password_form?key=<%= Api::Utils.java_facade.getComponentByClassname('emailnotifications', 'org.sonar.api.config.EmailSettings').class::SMTP_PASSWORD.to_s %>"
+             class="open-modal link-action">Edit</a>
+        <% end %>
         <p class="marginbottom10"><%= message('email_configuration.smtp_password.description') -%></p>
       </td>
     </tr>
index 9b965ee07b72cdf41928c61e5a743b4f94d582be..ee764458289e81e771e56832100cf95268a3e274 100644 (file)
@@ -5,7 +5,7 @@
                   $j('#loading_settings').show();
                   $j.ajax({ url:'<%= url_for :controller => 'settings', :action => 'update', :category => @category.key, :subcategory => @subcategory.key, :resource_id => (@resource && @resource.id) -%>',
                             type:'post',
-                            success:function(responseHTML){$j('#properties').html($j(responseHTML));$j('#loading_settings').hide();$j('#submit_settings').show()},
+                            success:function(responseHTML){$j('#properties').html($j(responseHTML));$j('#loading_settings').hide();$j('#submit_settings').show();$j('#properties').find('.open-modal').modal()},
                             data:$j(this).serialize()});
                   return false;"
          method='post'
         </tbody>
        </table>
        </div>
-      <% else 
+      <% else
          help = category_help(@category)
          unless help.blank?
       -%>
         <div class="help marginbottom10" style="margin-left: -1px">
           <%= help -%>
         </div>
-      <% end 
+      <% end
       end
       -%>
 
   </form>
   <% end -%>
 
-
-
 <script>
   $j(document)
-    .on('click', '.delete', function () {
-      $j(this).parents('.multi_value').remove();
-      return false;
-    })
-    .on('click', '.add_value', function () {
-      var template = $j(this).parents('.property').find('.template').last();
-      template.clone().insertBefore(template).show();
-      return false;
-    })
-    .on('keypress', 'form', function (e) {
-      if (e.which == 13 && e.target.nodeName != "TEXTAREA") {
-        /* See https://jira.codehaus.org/browse/SONAR-4363 */
-        submit_settings.click();
+      .on('click', '.delete', function () {
+        $j(this).parents('.multi_value').remove();
+        return false;
+      })
+      .on('click', '.add_value', function () {
+        var template = $j(this).parents('.property').find('.template').last();
+        template.clone().insertBefore(template).show();
         return false;
-      }
-    });
+      })
+      .on('keypress', 'form', function (e) {
+        if (e.which == 13 && e.target.nodeName != "TEXTAREA") {
+          /* See https://jira.codehaus.org/browse/SONAR-4363 */
+          submit_settings.click();
+          return false;
+        }
+      });
 </script>
index 57d5a57d7c7c3f1e046720ce0ce135dc54905198..c198581ba7aa213f46f911196e1f2b8eabc2f811 100644 (file)
       <% value = Property.value(key, resource_id) -%>
       <% errors << (render "settings/error", :key => key) -%>
     <% end -%>
-
-    <% if field == key_field -%>
-      <td><%= render "settings/type_#{field.type}", :property => field, :field => field, :value => value, :name => "property_sets[#{property.key}][]", :id => "input_#{h field.key}", :size => field.indicativeSize -%></td>
-    <% else -%>
-      <td><%= render "settings/type_#{field.type}", :property => field, :field => field, :value => value, :name => "#{property.key}[#{field.key}][]", :id => "input_#{h field.key}", :size => field.indicativeSize -%></td>
-    <% end -%>
+    <% name = field == key_field ? "property_sets[#{property.key}][]" : "#{property.key}[#{field.key}][]" %>
+    <td><%= render "settings/type_#{field.type}", :property => field, :field => field, :value => value, :name => name, :property_key => key,
+                   :id => "input_#{h field.key}", :size => field.indicativeSize -%></td>
   <% end -%>
 
   <td style="width: 60px;">
index 68bc7edb71a1bebe299bdbeb43fe48f0517e8a36..66a1ded8ae72ed94a81c180ee9bb31acf4525bab 100644 (file)
@@ -2,4 +2,13 @@
    options = {:id => id}
    options[:size] = (defined? size) ? size : nil
 %>
-<%= property_input_field(name, PropertyType::TYPE_PASSWORD, value, PropertiesHelper::SCREEN_SETTINGS, options) %>
\ No newline at end of file
+
+<% if value.blank? %>
+  <%= property_input_field(name, PropertyType::TYPE_PASSWORD, value, PropertiesHelper::SCREEN_SETTINGS, options) %>
+<% else %>
+  <% key = (defined? property_key) ? property_key : property.key %>
+  <span class="marginright10">**********</span>
+  <a id="update-password-<%= u id %>" href="<%=ApplicationController.root_context-%>/settings/update_password_form?key=<%= u key %>&component_id=<%= u @resource && @resource.id %>"
+     class="open-modal link-action">Edit</a>
+  <input type="hidden" name="<%= name %>">
+<% end %>
diff --git a/server/sonar-web/src/main/webapp/WEB-INF/app/views/settings/_update_password_form.html.erb b/server/sonar-web/src/main/webapp/WEB-INF/app/views/settings/_update_password_form.html.erb
new file mode 100644 (file)
index 0000000..0d3d738
--- /dev/null
@@ -0,0 +1,26 @@
+<form id="edit_password" method="post" action="<%= ApplicationController.root_context -%>/settings/update_password">
+  <fieldset>
+    <div class="modal-head">
+      <h2>Update Password '<%= @key %>'</h2>
+    </div>
+    <div class="modal-body">
+      <div class="modal-error"></div>
+      <div class="modal-field">
+        <input type="hidden" value="<%= @key %>" name="key" id="key"/>
+        <input type="hidden" value="<%= @component_id %>" name="component_id" id="component_id"/>
+      </div>
+      <div class="modal-field">
+        <label for="password">Password</label>
+        <input type="password" size="50" name="password" id="password" autocomplete="off">
+      </div>
+    </div>
+    <div class="modal-foot">
+      <input type="submit" value="Save" name="commit">
+      <a class="action" href="#" onclick="return closeModalWindow()"><%= h message('cancel') -%></a>
+    </div>
+  </fieldset>
+</form>
+
+<script>
+  $j("#edit_password").modalForm();
+</script>