Fix #2785: Allow changing API key; require password to view or change key.

This commit is contained in:
evazion
2016-12-17 22:32:01 -06:00
parent 3e285ea4ce
commit a92120e873
12 changed files with 201 additions and 78 deletions

View File

@@ -0,0 +1,11 @@
@import "../common/020_base.css.scss";
#c-maintenance-user-api-keys {
#api-key {
@extend code;
}
.button_to {
display: inline-block;
}
}

View File

@@ -1,17 +0,0 @@
class ApiKeysController < ApplicationController
before_filter :member_only
def new
@api_key = ApiKey.new(:user_id => CurrentUser.user.id)
end
def create
@api_key = ApiKey.generate!(CurrentUser.user)
if @api_key.errors.empty?
redirect_to user_path(CurrentUser.user), :notice => "API key generated"
else
render :action => "new"
end
end
end

View File

@@ -0,0 +1,44 @@
module Maintenance
module User
class ApiKeysController < ApplicationController
before_filter :member_only
before_filter :check_privilege
before_filter :authenticate!, :except => [:show]
rescue_from ::SessionLoader::AuthenticationFailure, :with => :authentication_failed
respond_to :html, :json, :xml
def view
respond_with(CurrentUser.user, @api_key)
end
def update
@api_key.regenerate!
respond_with(CurrentUser.user, @api_key) { |format| format.js }
end
def destroy
@api_key.destroy
respond_with(CurrentUser.user, @api_key, location: CurrentUser.user)
end
protected
def check_privilege
raise ::User::PrivilegeError unless params[:user_id].to_i == CurrentUser.id
end
def authenticate!
if ::User.authenticate(CurrentUser.user.name, params[:user][:password]) == CurrentUser.user
@api_key = CurrentUser.user.api_key || ApiKey.generate!(CurrentUser.user)
@password = params[:user][:password]
else
raise ::SessionLoader::AuthenticationFailure
end
end
def authentication_failed
redirect_to(user_api_key_path(CurrentUser.user), :notice => "Password was incorrect.")
end
end
end
end

View File

@@ -7,4 +7,8 @@ class ApiKey < ActiveRecord::Base
def self.generate!(user)
create(:user_id => user.id, :key => SecureRandom.urlsafe_base64(32))
end
def regenerate!
update!(:key => SecureRandom.urlsafe_base64(32))
end
end

View File

@@ -1,19 +0,0 @@
<div id="c-api-keys">
<div id="a-new">
<h1>New API Key</h1>
<p>You can generate a new API key to authenticate against <%= Danbooru.config.app_name %>.</p>
<%= error_messages_for :api_key %>
<%= simple_form_for(@api_key) do |f| %>
<%= submit_tag "Generate" %>
<% end %>
</div>
</div>
<%= render "users/secondary_links" %>
<% content_for(:page_title) do %>
New API Key - <%= Danbooru.config.app_name %>
<% end %>

View File

@@ -0,0 +1,15 @@
<div id="c-maintenance-user-api-keys">
<div id="a-show">
<h1>API Key</h1>
<p>You must re-enter your password to view or change your API key.</p>
<%= simple_form_for CurrentUser.user, url: view_user_api_key_path(CurrentUser.user), method: :post do |f| %>
<%= f.input :password, :as => :password, :input_html => {:autocomplete => "off"} %>
<%= f.button :submit, "Submit" %>
<% end %>
</div>
</div>
<% content_for(:page_title) do %>
API Key - <%= Danbooru.config.app_name %>
<% end %>

View File

@@ -0,0 +1,9 @@
<% if @api_key.errors.any? %>
Danbooru.error("<%= j @api_key.errors.full_messages.join(', ') %>");
<% else %>
$("#api-key").text("<%= j @api_key.key %>");
$("#api-key-created").html("<%= j compact_time @api_key.created_at %>");
$("#api-key-updated").html("<%= j compact_time @api_key.updated_at %>");
Danbooru.notice("API key regenerated.");
<% end %>

View File

@@ -0,0 +1,32 @@
<div id="c-maintenance-user-api-keys">
<div id="a-view">
<h1>API Key</h1>
<table class="striped" width="100%">
<thead>
<tr>
<th>API Key</th>
<th>Created</th>
<th>Updated</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td id="api-key"><%= @api_key.key %></td>
<td id="api-key-created"><%= compact_time @api_key.created_at %></td>
<td id="api-key-updated"><%= compact_time @api_key.updated_at %></td>
<td>
<%= button_to "Regenerate", user_api_key_path(CurrentUser.user), method: :put, params: { 'user[password]': @password }, remote: true %>
<%= button_to "Delete", user_api_key_path(CurrentUser.user), method: :delete, params: { 'user[password]': @password } %>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<% content_for(:page_title) do %>
API Key - <%= Danbooru.config.app_name %>
<% end %>

View File

@@ -147,11 +147,8 @@
<tr>
<th>API Key</th>
<td>
<% if CurrentUser.user.api_key %>
<%= CurrentUser.user.api_key.key %>
<% else %>
<%= link_to "Generate key", new_api_key_path %>
<% end %>
<%= link_to (CurrentUser.api_key ? "View" : "Generate"), user_api_key_path(CurrentUser.user) %>
(<%= link_to "help", wiki_pages_path(title: "help:api") %>)
</td>
</tr>
<% end %>