diff options
author | Kamil Trzcinski <ayufan@ayufan.eu> | 2016-11-13 20:35:47 +0100 |
---|---|---|
committer | Kamil Trzcinski <ayufan@ayufan.eu> | 2016-11-16 13:42:35 +0100 |
commit | c60437786bfe43344b4a5eb040437f73f37c6396 (patch) | |
tree | fe90ee0dd9e556369e7f53ce4a03e2751b486682 | |
parent | c5169b5d447ab6c73bbe542c071a4054c5969165 (diff) | |
download | gitlab-ce-c60437786bfe43344b4a5eb040437f73f37c6396.tar.gz |
Create relation between chat user and GitLab user and allow to authorize them [ci skip]
-rw-r--r-- | app/controllers/profiles/chat_names_controller.rb | 64 | ||||
-rw-r--r-- | app/models/chat_name.rb | 12 | ||||
-rw-r--r-- | app/models/user.rb | 1 | ||||
-rw-r--r-- | app/services/chat_names/find_user_service.rb | 15 | ||||
-rw-r--r-- | app/services/chat_names/request_service.rb | 32 | ||||
-rw-r--r-- | app/views/layouts/nav/_profile.html.haml | 4 | ||||
-rw-r--r-- | app/views/profiles/chat_names/index.html.haml | 49 | ||||
-rw-r--r-- | app/views/profiles/chat_names/new.html.haml | 15 | ||||
-rw-r--r-- | config/routes/profile.rb | 6 | ||||
-rw-r--r-- | db/migrate/20161113184239_create_user_chat_names_table.rb | 20 | ||||
-rw-r--r-- | db/schema.rb | 16 | ||||
-rw-r--r-- | lib/gitlab/chat_name_token.rb | 45 |
12 files changed, 278 insertions, 1 deletions
diff --git a/app/controllers/profiles/chat_names_controller.rb b/app/controllers/profiles/chat_names_controller.rb new file mode 100644 index 00000000000..8c5b83adaf4 --- /dev/null +++ b/app/controllers/profiles/chat_names_controller.rb @@ -0,0 +1,64 @@ +class Profiles::ChatNamesController < Profiles::ApplicationController + before_action :chat_names + before_action :chat_name_token, only: [:new] + before_action :chat_name_params, only: [:new, :create, :deny] + + def index + end + + def new + end + + def create + new_chat_name = current_user.chat_names.new(chat_name_params) + + if new_chat_name.save + flash[:notice] = "Authorized chat nickname #{new_chat_name.chat_name}" + else + flash[:alert] = "Could not authorize chat nickname. Try again!" + end + + delete_chat_name_token + redirect_to profile_chat_names_path + end + + def deny + delete_chat_name_token + + flash[:alert] = "Denied authorization of chat nickname #{chat_name_params[:user_name]}" + + redirect_to profile_chat_names_path + end + + def destroy + @chat_name = chat_names.find(params[:id]) + + if @chat_name.destroy + flash[:notice] = "Delete chat nickname: #{@chat_name.chat_name}!" + else + flash[:alert] = "Could not delete chat nickname #{@chat_name.chat_name}." + end + + redirect_to profile_chat_names_path + end + + private + + def delete_chat_name_token + chat_name_token.delete + end + + def chat_name_params + @chat_name_params ||= chat_name_token.get || render_404 + end + + def chat_name_token + return render_404 unless params[:token] || render_404 + + @chat_name_token ||= Gitlab::ChatNameToken.new(params[:token]) + end + + def chat_names + @chat_names ||= current_user.chat_names + end +end diff --git a/app/models/chat_name.rb b/app/models/chat_name.rb new file mode 100644 index 00000000000..f321db75eeb --- /dev/null +++ b/app/models/chat_name.rb @@ -0,0 +1,12 @@ +class ChatName < ActiveRecord::Base + belongs_to :service + belongs_to :user + + validates :user, presence: true + validates :service, presence: true + validates :team_id, presence: true + validates :chat_id, presence: true + + validates :user_id, uniqueness: { scope: [:service_id] } + validates :chat_id, uniqueness: { scope: [:service_id, :team_id] } +end diff --git a/app/models/user.rb b/app/models/user.rb index 3813df6684e..10fe69818b6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -56,6 +56,7 @@ class User < ActiveRecord::Base has_many :personal_access_tokens, dependent: :destroy has_many :identities, dependent: :destroy, autosave: true has_many :u2f_registrations, dependent: :destroy + has_many :chat_names, dependent: :destroy # Groups has_many :members, dependent: :destroy diff --git a/app/services/chat_names/find_user_service.rb b/app/services/chat_names/find_user_service.rb new file mode 100644 index 00000000000..6b7f75430a8 --- /dev/null +++ b/app/services/chat_names/find_user_service.rb @@ -0,0 +1,15 @@ +module ChatNames + class FindUserService + def initialize(chat_names, params) + @chat_names = chat_names + @params = params + end + + def execute + @chat_names.find_by( + team_id: @params[:team_id], + chat_id: @params[:user_id] + ) + end + end +end diff --git a/app/services/chat_names/request_service.rb b/app/services/chat_names/request_service.rb new file mode 100644 index 00000000000..c67b93f932f --- /dev/null +++ b/app/services/chat_names/request_service.rb @@ -0,0 +1,32 @@ +module ChatNames + class RequestService + include Gitlab::Routing.url_helpers + + def initialize(service, params) + @service = service + @params = params + end + + def execute + token = chat_name_token.store!(chat_name_params) + + new_profile_chat_name_url(token: token) if token + end + + private + + def chat_name_token + Gitlab::ChatNameToken.new + end + + def chat_name_params + { + service_id: @service.id, + team_id: @params[:team_id], + team_domain: @params[:team_domain], + chat_id: @params[:user_id], + chat_name: @params[:user_name] + } + end + end +end diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml index 6d514f669db..e06301bda14 100644 --- a/app/views/layouts/nav/_profile.html.haml +++ b/app/views/layouts/nav/_profile.html.haml @@ -17,6 +17,10 @@ = link_to applications_profile_path, title: 'Applications' do %span Applications + = nav_link(controller: :chat_names) do + = link_to profile_chat_names_path, title: 'Chat' do + %span + Chat = nav_link(controller: :personal_access_tokens) do = link_to profile_personal_access_tokens_path, title: 'Access Tokens' do %span diff --git a/app/views/profiles/chat_names/index.html.haml b/app/views/profiles/chat_names/index.html.haml new file mode 100644 index 00000000000..f90ac4c6a03 --- /dev/null +++ b/app/views/profiles/chat_names/index.html.haml @@ -0,0 +1,49 @@ +- page_title "Chat" += render 'profiles/head' + +.row.prepend-top-default + .col-lg-3.profile-settings-sidebar + %h4.prepend-top-0 + = page_title + %p + You can see your Chat integrations. + + .col-lg-9 + %h5 Active chat names (#{@chat_names.length}) + + - if @chat_names.present? + .table-responsive + %table.table.chat-names + %thead + %tr + %th Project + %th Service + %th Team domain + %th Nickname + %th Created + %th + %tbody + - @chat_names.each do |chat_name| + - service = chat_name.service + - project = service.project + %tr + %td + %strong + - if can?(current_user, :read_project, project) + = link_to project.name_with_namespace, project_path(project) + - else + .light N/A + %td + %strong + - if can?(current_user, :admin_project, project) + = link_to service.title, edit_namespace_project_service_path(project.namespace, project, service) + - else + = chat_name.service.title + %td= chat_name.team_domain + %td= chat_name.chat_name + %td= chat_name.created_at + %td= link_to "Remove", profile_chat_name_path(chat_name), method: :delete, class: "btn btn-danger pull-right", data: { confirm: "Are you sure you want to revoke this nickname?" } + + - else + .settings-message.text-center + You don't have any active chat names. diff --git a/app/views/profiles/chat_names/new.html.haml b/app/views/profiles/chat_names/new.html.haml new file mode 100644 index 00000000000..0b9ee8c71ad --- /dev/null +++ b/app/views/profiles/chat_names/new.html.haml @@ -0,0 +1,15 @@ +%h3.page-title Authorization required +%main{:role => "main"} + %p.h4 + Authorize the chat user + %strong.text-info= @chat_name_params[:chat_name] + to use your account? + + %hr/ + .actions + = form_tag profile_chat_names_path, method: :post do + = hidden_field_tag :token, @chat_name_token.token + = submit_tag "Authorize", class: "btn btn-success wide pull-left" + = form_tag deny_profile_chat_names_path, method: :delete do + = hidden_field_tag :token, @chat_name_token.token + = submit_tag "Deny", class: "btn btn-danger prepend-left-10" diff --git a/config/routes/profile.rb b/config/routes/profile.rb index 52b9a565db8..6b91485da9e 100644 --- a/config/routes/profile.rb +++ b/config/routes/profile.rb @@ -23,6 +23,12 @@ resource :profile, only: [:show, :update] do resource :preferences, only: [:show, :update] resources :keys, only: [:index, :show, :new, :create, :destroy] resources :emails, only: [:index, :create, :destroy] + resources :chat_names, only: [:index, :new, :create, :destroy] do + collection do + delete :deny + end + end + resource :avatar, only: [:destroy] resources :personal_access_tokens, only: [:index, :create] do diff --git a/db/migrate/20161113184239_create_user_chat_names_table.rb b/db/migrate/20161113184239_create_user_chat_names_table.rb new file mode 100644 index 00000000000..f9ab2adf2a9 --- /dev/null +++ b/db/migrate/20161113184239_create_user_chat_names_table.rb @@ -0,0 +1,20 @@ +class CreateUserChatNamesTable < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + create_table :chat_names do |t| + t.integer "user_id", null: false + t.integer "service_id", null: false + t.string "team_id" + t.string "team_domain" + t.string "chat_id" + t.string "chat_name" + t.timestamps + end + + add_index :chat_names, [:user_id, :service_id], unique: true + add_index :chat_names, [:service_id, :team_id, :chat_id], unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index 62c325a52d7..5f25f0a305f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20161106185620) do +ActiveRecord::Schema.define(version: 20161113184239) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -149,6 +149,20 @@ ActiveRecord::Schema.define(version: 20161106185620) do t.text "message_html" end + create_table "chat_names", force: :cascade do |t| + t.integer "user_id", null: false + t.integer "service_id", null: false + t.string "team_id" + t.string "team_domain" + t.string "chat_id" + t.string "chat_name" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "chat_names", ["service_id", "team_id", "user_id"], name: "index_chat_names_on_service_id_and_team_id_and_user_id", unique: true, using: :btree + add_index "chat_names", ["user_id", "service_id"], name: "index_chat_names_on_user_id_and_service_id", unique: true, using: :btree + create_table "ci_application_settings", force: :cascade do |t| t.boolean "all_broken_builds" t.boolean "add_pusher" diff --git a/lib/gitlab/chat_name_token.rb b/lib/gitlab/chat_name_token.rb new file mode 100644 index 00000000000..c8349839219 --- /dev/null +++ b/lib/gitlab/chat_name_token.rb @@ -0,0 +1,45 @@ +require 'json' + +module Gitlab + class ChatNameToken + attr_reader :token + + TOKEN_LENGTH = 50 + EXPIRY_TIME = 1800 + + def initialize(token = new_token) + @token = token + end + + def get + Gitlab::Redis.with do |redis| + data = redis.get(redis_key) + JSON.parse(data, symbolize_names: true) if data + end + end + + def store!(params) + Gitlab::Redis.with do |redis| + params = params.to_json + redis.set(redis_key, params, ex: EXPIRY_TIME) + token + end + end + + def delete + Gitlab::Redis.with do |redis| + redis.del(redis_key) + end + end + + private + + def new_token + Devise.friendly_token(TOKEN_LENGTH) + end + + def redis_key + "gitlab:chat_names:#{token}" + end + end +end |