Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorValery Sizov <vsv2711@gmail.com>2014-12-19 17:15:29 +0300
committerValery Sizov <vsv2711@gmail.com>2014-12-24 16:38:07 +0300
commite41dadcb33fda44ee274daa673bd933e13aa90eb (patch)
treeef0dc6ecea0020fe1ce8598342bcbf7e620984fe /app
parent5cf2bd4c997d84e9a02d722d6ba870c24b06cc0f (diff)
Doorkeeper integration
Diffstat (limited to 'app')
-rw-r--r--app/controllers/oauth/applications_controller.rb25
-rw-r--r--app/controllers/oauth/authorizations_controller.rb57
-rw-r--r--app/controllers/oauth/authorized_applications_controller.rb8
-rw-r--r--app/controllers/profiles/accounts_controller.rb2
-rw-r--r--app/models/user.rb1
-rw-r--r--app/services/oauth2/access_token_validation_service.rb41
-rw-r--r--app/views/doorkeeper/applications/_delete_form.html.haml4
-rw-r--r--app/views/doorkeeper/applications/_form.html.haml25
-rw-r--r--app/views/doorkeeper/applications/edit.html.haml2
-rw-r--r--app/views/doorkeeper/applications/index.html.haml16
-rw-r--r--app/views/doorkeeper/applications/new.html.haml2
-rw-r--r--app/views/doorkeeper/applications/show.html.haml21
-rw-r--r--app/views/doorkeeper/authorizations/error.html.haml3
-rw-r--r--app/views/doorkeeper/authorizations/new.html.haml28
-rw-r--r--app/views/doorkeeper/authorizations/show.html.haml3
-rw-r--r--app/views/doorkeeper/authorized_applications/_delete_form.html.haml4
-rw-r--r--app/views/doorkeeper/authorized_applications/index.html.haml16
-rw-r--r--app/views/layouts/doorkeeper/admin.html.erb34
-rw-r--r--app/views/layouts/doorkeeper/application.html.erb23
-rw-r--r--app/views/layouts/nav/_profile.html.haml2
-rw-r--r--app/views/profiles/accounts/show.html.haml35
21 files changed, 351 insertions, 1 deletions
diff --git a/app/controllers/oauth/applications_controller.rb b/app/controllers/oauth/applications_controller.rb
new file mode 100644
index 00000000000..8eafe5e3b3d
--- /dev/null
+++ b/app/controllers/oauth/applications_controller.rb
@@ -0,0 +1,25 @@
+class Oauth::ApplicationsController < Doorkeeper::ApplicationsController
+ before_filter :authenticate_user!
+ layout "profile"
+
+ def index
+ @applications = current_user.oauth_applications
+ end
+
+ def create
+ @application = Doorkeeper::Application.new(application_params)
+ @application.owner = current_user if Doorkeeper.configuration.confirm_application_owner?
+ if @application.save
+ flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :create])
+ redirect_to oauth_application_url(@application)
+ else
+ render :new
+ end
+ end
+
+ def destroy
+ flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :destroy]) if @application.destroy
+ redirect_to profile_account_url
+ end
+
+end \ No newline at end of file
diff --git a/app/controllers/oauth/authorizations_controller.rb b/app/controllers/oauth/authorizations_controller.rb
new file mode 100644
index 00000000000..c46707e2c77
--- /dev/null
+++ b/app/controllers/oauth/authorizations_controller.rb
@@ -0,0 +1,57 @@
+class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
+ before_filter :authenticate_resource_owner!
+ layout "profile"
+
+ def new
+ if pre_auth.authorizable?
+ if skip_authorization? || matching_token?
+ auth = authorization.authorize
+ redirect_to auth.redirect_uri
+ else
+ render "doorkeeper/authorizations/new"
+ end
+ else
+ render "doorkeeper/authorizations/error"
+ end
+ end
+
+ # TODO: Handle raise invalid authorization
+ def create
+ redirect_or_render authorization.authorize
+ end
+
+ def destroy
+ redirect_or_render authorization.deny
+ end
+
+ private
+
+ def matching_token?
+ Doorkeeper::AccessToken.matching_token_for pre_auth.client,
+ current_resource_owner.id,
+ pre_auth.scopes
+ end
+
+ def redirect_or_render(auth)
+ if auth.redirectable?
+ redirect_to auth.redirect_uri
+ else
+ render json: auth.body, status: auth.status
+ end
+ end
+
+ def pre_auth
+ @pre_auth ||= Doorkeeper::OAuth::PreAuthorization.new(Doorkeeper.configuration,
+ server.client_via_uid,
+ params)
+ end
+
+ def authorization
+ @authorization ||= strategy.request
+ end
+
+ def strategy
+ @strategy ||= server.authorization_request pre_auth.response_type
+ end
+end
+
diff --git a/app/controllers/oauth/authorized_applications_controller.rb b/app/controllers/oauth/authorized_applications_controller.rb
new file mode 100644
index 00000000000..b6d4a99c0a9
--- /dev/null
+++ b/app/controllers/oauth/authorized_applications_controller.rb
@@ -0,0 +1,8 @@
+class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicationsController
+ layout "profile"
+
+ def destroy
+ Doorkeeper::AccessToken.revoke_all_for params[:id], current_resource_owner
+ redirect_to profile_account_url, notice: I18n.t(:notice, scope: [:doorkeeper, :flash, :authorized_applications, :destroy])
+ end
+end \ No newline at end of file
diff --git a/app/controllers/profiles/accounts_controller.rb b/app/controllers/profiles/accounts_controller.rb
index fe121691a10..5f15378c831 100644
--- a/app/controllers/profiles/accounts_controller.rb
+++ b/app/controllers/profiles/accounts_controller.rb
@@ -3,5 +3,7 @@ class Profiles::AccountsController < ApplicationController
def show
@user = current_user
+ @applications = current_user.oauth_applications
+ @authorized_applications = Doorkeeper::Application.authorized_for(current_user)
end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 7faeef1b5b0..6518fc50b70 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -106,6 +106,7 @@ class User < ActiveRecord::Base
has_many :recent_events, -> { order "id DESC" }, foreign_key: :author_id, class_name: "Event"
has_many :assigned_issues, dependent: :destroy, foreign_key: :assignee_id, class_name: "Issue"
has_many :assigned_merge_requests, dependent: :destroy, foreign_key: :assignee_id, class_name: "MergeRequest"
+ has_many :oauth_applications, class_name: 'Doorkeeper::Application', as: :owner, dependent: :destroy
#
diff --git a/app/services/oauth2/access_token_validation_service.rb b/app/services/oauth2/access_token_validation_service.rb
new file mode 100644
index 00000000000..95283489753
--- /dev/null
+++ b/app/services/oauth2/access_token_validation_service.rb
@@ -0,0 +1,41 @@
+module Oauth2::AccessTokenValidationService
+ # Results:
+ VALID = :valid
+ EXPIRED = :expired
+ REVOKED = :revoked
+ INSUFFICIENT_SCOPE = :insufficient_scope
+
+ class << self
+ def validate(token, scopes: [])
+ if token.expired?
+ return EXPIRED
+
+ elsif token.revoked?
+ return REVOKED
+
+ elsif !self.sufficent_scope?(token, scopes)
+ return INSUFFICIENT_SCOPE
+
+ else
+ return VALID
+ end
+ end
+
+ protected
+ # True if the token's scope is a superset of required scopes,
+ # or the required scopes is empty.
+ def sufficent_scope?(token, scopes)
+ if scopes.blank?
+ # if no any scopes required, the scopes of token is sufficient.
+ return true
+ else
+ # If there are scopes required, then check whether
+ # the set of authorized scopes is a superset of the set of required scopes
+ required_scopes = Set.new(scopes)
+ authorized_scopes = Set.new(token.scopes)
+
+ return authorized_scopes >= required_scopes
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/app/views/doorkeeper/applications/_delete_form.html.haml b/app/views/doorkeeper/applications/_delete_form.html.haml
new file mode 100644
index 00000000000..bf8098f38d0
--- /dev/null
+++ b/app/views/doorkeeper/applications/_delete_form.html.haml
@@ -0,0 +1,4 @@
+- submit_btn_css ||= 'btn btn-link btn-remove btn-small'
+= form_tag oauth_application_path(application) do
+ %input{:name => "_method", :type => "hidden", :value => "delete"}/
+ = submit_tag 'Destroy', onclick: "return confirm('Are you sure?')", class: submit_btn_css \ No newline at end of file
diff --git a/app/views/doorkeeper/applications/_form.html.haml b/app/views/doorkeeper/applications/_form.html.haml
new file mode 100644
index 00000000000..45ddf16ad0b
--- /dev/null
+++ b/app/views/doorkeeper/applications/_form.html.haml
@@ -0,0 +1,25 @@
+= form_for application, url: doorkeeper_submit_path(application), html: {class: 'form-horizontal', role: 'form'} do |f|
+ - if application.errors.any?
+ .alert.alert-danger{"data-alert" => ""}
+ %p Whoops! Check your form for possible errors
+ = content_tag :div, class: "form-group#{' has-error' if application.errors[:name].present?}" do
+ = f.label :name, class: 'col-sm-2 control-label'
+ .col-sm-10
+ = f.text_field :name, class: 'form-control'
+ = doorkeeper_errors_for application, :name
+ = content_tag :div, class: "form-group#{' has-error' if application.errors[:redirect_uri].present?}" do
+ = f.label :redirect_uri, class: 'col-sm-2 control-label'
+ .col-sm-10
+ = f.text_area :redirect_uri, class: 'form-control'
+ = doorkeeper_errors_for application, :redirect_uri
+ %span.help-block
+ Use one line per URI
+ - if Doorkeeper.configuration.native_redirect_uri
+ %span.help-block
+ Use
+ %code= Doorkeeper.configuration.native_redirect_uri
+ for local tests
+ .form-group
+ .col-sm-offset-2.col-sm-10
+ = f.submit 'Submit', class: "btn btn-primary wide"
+ = link_to "Cancel", profile_account_path, :class => "btn btn-default" \ No newline at end of file
diff --git a/app/views/doorkeeper/applications/edit.html.haml b/app/views/doorkeeper/applications/edit.html.haml
new file mode 100644
index 00000000000..61584eb9c49
--- /dev/null
+++ b/app/views/doorkeeper/applications/edit.html.haml
@@ -0,0 +1,2 @@
+%h3.page-title Edit application
+= render 'form', application: @application \ No newline at end of file
diff --git a/app/views/doorkeeper/applications/index.html.haml b/app/views/doorkeeper/applications/index.html.haml
new file mode 100644
index 00000000000..e5be4b4bcac
--- /dev/null
+++ b/app/views/doorkeeper/applications/index.html.haml
@@ -0,0 +1,16 @@
+%h3.page-title Your applications
+%p= link_to 'New Application', new_oauth_application_path, class: 'btn btn-success'
+%table.table.table-striped
+ %thead
+ %tr
+ %th Name
+ %th Callback URL
+ %th
+ %th
+ %tbody
+ - @applications.each do |application|
+ %tr{:id => "application_#{application.id}"}
+ %td= link_to application.name, oauth_application_path(application)
+ %td= application.redirect_uri
+ %td= link_to 'Edit', edit_oauth_application_path(application), class: 'btn btn-link'
+ %td= render 'delete_form', application: application \ No newline at end of file
diff --git a/app/views/doorkeeper/applications/new.html.haml b/app/views/doorkeeper/applications/new.html.haml
new file mode 100644
index 00000000000..655845e4af5
--- /dev/null
+++ b/app/views/doorkeeper/applications/new.html.haml
@@ -0,0 +1,2 @@
+%h3.page-title New application
+= render 'form', application: @application \ No newline at end of file
diff --git a/app/views/doorkeeper/applications/show.html.haml b/app/views/doorkeeper/applications/show.html.haml
new file mode 100644
index 00000000000..5236b865896
--- /dev/null
+++ b/app/views/doorkeeper/applications/show.html.haml
@@ -0,0 +1,21 @@
+%h3.page-title
+ Application: #{@application.name}
+.row
+ .col-md-8
+ %h4 Application Id:
+ %p
+ %code#application_id= @application.uid
+ %h4 Secret:
+ %p
+ %code#secret= @application.secret
+ %h4 Callback urls:
+ %table
+ - @application.redirect_uri.split.each do |uri|
+ %tr
+ %td
+ %code= uri
+ %td
+ = link_to 'Authorize', oauth_authorization_path(client_id: @application.uid, redirect_uri: uri, response_type: 'code'), class: 'btn btn-success', target: '_blank'
+.prepend-top-20
+ %p= link_to 'Edit', edit_oauth_application_path(@application), class: 'btn btn-primary wide pull-left'
+ %p= render 'delete_form', application: @application, submit_btn_css: 'btn btn-danger prepend-left-10' \ No newline at end of file
diff --git a/app/views/doorkeeper/authorizations/error.html.haml b/app/views/doorkeeper/authorizations/error.html.haml
new file mode 100644
index 00000000000..7561ec85ed9
--- /dev/null
+++ b/app/views/doorkeeper/authorizations/error.html.haml
@@ -0,0 +1,3 @@
+%h3.page-title An error has occurred
+%main{:role => "main"}
+ %pre= @pre_auth.error_response.body[:error_description] \ No newline at end of file
diff --git a/app/views/doorkeeper/authorizations/new.html.haml b/app/views/doorkeeper/authorizations/new.html.haml
new file mode 100644
index 00000000000..15f9ee266c1
--- /dev/null
+++ b/app/views/doorkeeper/authorizations/new.html.haml
@@ -0,0 +1,28 @@
+%h3.page-title Authorize required
+%main{:role => "main"}
+ %p.h4
+ Authorize
+ %strong.text-info= @pre_auth.client.name
+ to use your account?
+ - if @pre_auth.scopes
+ #oauth-permissions
+ %p This application will be able to:
+ %ul.text-info
+ - @pre_auth.scopes.each do |scope|
+ %li= t scope, scope: [:doorkeeper, :scopes]
+ %hr/
+ .actions
+ = form_tag oauth_authorization_path, method: :post do
+ = hidden_field_tag :client_id, @pre_auth.client.uid
+ = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri
+ = hidden_field_tag :state, @pre_auth.state
+ = hidden_field_tag :response_type, @pre_auth.response_type
+ = hidden_field_tag :scope, @pre_auth.scope
+ = submit_tag "Authorize", class: "btn btn-success wide pull-left"
+ = form_tag oauth_authorization_path, method: :delete do
+ = hidden_field_tag :client_id, @pre_auth.client.uid
+ = hidden_field_tag :redirect_uri, @pre_auth.redirect_uri
+ = hidden_field_tag :state, @pre_auth.state
+ = hidden_field_tag :response_type, @pre_auth.response_type
+ = hidden_field_tag :scope, @pre_auth.scope
+ = submit_tag "Deny", class: "btn btn-danger prepend-left-10" \ No newline at end of file
diff --git a/app/views/doorkeeper/authorizations/show.html.haml b/app/views/doorkeeper/authorizations/show.html.haml
new file mode 100644
index 00000000000..9a402007194
--- /dev/null
+++ b/app/views/doorkeeper/authorizations/show.html.haml
@@ -0,0 +1,3 @@
+%h3.page-title Authorization code:
+%main{:role => "main"}
+ %code#authorization_code= params[:code] \ No newline at end of file
diff --git a/app/views/doorkeeper/authorized_applications/_delete_form.html.haml b/app/views/doorkeeper/authorized_applications/_delete_form.html.haml
new file mode 100644
index 00000000000..5cbb4a70c19
--- /dev/null
+++ b/app/views/doorkeeper/authorized_applications/_delete_form.html.haml
@@ -0,0 +1,4 @@
+- submit_btn_css ||= 'btn btn-link btn-remove'
+= form_tag oauth_authorized_application_path(application) do
+ %input{:name => "_method", :type => "hidden", :value => "delete"}/
+ = submit_tag 'Revoke', onclick: "return confirm('Are you sure?')", class: 'btn btn-link btn-remove btn-small' \ No newline at end of file
diff --git a/app/views/doorkeeper/authorized_applications/index.html.haml b/app/views/doorkeeper/authorized_applications/index.html.haml
new file mode 100644
index 00000000000..814cdc987ef
--- /dev/null
+++ b/app/views/doorkeeper/authorized_applications/index.html.haml
@@ -0,0 +1,16 @@
+%header.page-header
+ %h1 Your authorized applications
+%main{:role => "main"}
+ %table.table.table-striped
+ %thead
+ %tr
+ %th Application
+ %th Created At
+ %th
+ %th
+ %tbody
+ - @applications.each do |application|
+ %tr
+ %td= application.name
+ %td= application.created_at.strftime('%Y-%m-%d %H:%M:%S')
+ %td= render 'delete_form', application: application \ No newline at end of file
diff --git a/app/views/layouts/doorkeeper/admin.html.erb b/app/views/layouts/doorkeeper/admin.html.erb
new file mode 100644
index 00000000000..baeb5eb63fc
--- /dev/null
+++ b/app/views/layouts/doorkeeper/admin.html.erb
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Doorkeeper</title>
+ <%= stylesheet_link_tag "doorkeeper/admin/application" %>
+ <%= csrf_meta_tags %>
+</head>
+<body>
+<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
+ <div class="container">
+ <div class="navbar-header">
+ <%= link_to 'OAuth2 Provider', oauth_applications_path, class: 'navbar-brand' %>
+ </div>
+ <ul class="nav navbar-nav">
+ <%= content_tag :li, class: "#{'active' if request.path == oauth_applications_path}" do %>
+ <%= link_to 'Applications', oauth_applications_path %>
+ <% end %>
+ </ul>
+ </div>
+</div>
+<div class="container">
+ <%- if flash[:notice].present? %>
+ <div class="alert alert-info">
+ <%= flash[:notice] %>
+ </div>
+ <% end -%>
+
+ <%= yield %>
+</div>
+</body>
+</html>
diff --git a/app/views/layouts/doorkeeper/application.html.erb b/app/views/layouts/doorkeeper/application.html.erb
new file mode 100644
index 00000000000..fd7a31584f3
--- /dev/null
+++ b/app/views/layouts/doorkeeper/application.html.erb
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>OAuth authorize required</title>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+ <%= stylesheet_link_tag "doorkeeper/application" %>
+ <%= csrf_meta_tags %>
+</head>
+<body>
+<div id="container">
+ <%- if flash[:notice].present? %>
+ <div class="alert alert-info">
+ <%= flash[:notice] %>
+ </div>
+ <% end -%>
+
+ <%= yield %>
+</div>
+</body>
+</html>
diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml
index 05ba20e3611..f68fe87a75b 100644
--- a/app/views/layouts/nav/_profile.html.haml
+++ b/app/views/layouts/nav/_profile.html.haml
@@ -3,7 +3,7 @@
= link_to profile_path, title: "Profile" do
%i.fa.fa-user
Profile
- = nav_link(controller: :accounts) do
+ = nav_link(controller: [:accounts, :applications]) do
= link_to profile_account_path do
%i.fa.fa-gear
Account
diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml
index a21dcff41c0..1d0b6d77189 100644
--- a/app/views/profiles/accounts/show.html.haml
+++ b/app/views/profiles/accounts/show.html.haml
@@ -75,3 +75,38 @@
The following groups will be abandoned. You should transfer or remove them:
%strong #{current_user.solo_owned_groups.map(&:name).join(', ')}
= link_to 'Delete account', user_registration_path, data: { confirm: "REMOVE #{current_user.name}? Are you sure?" }, method: :delete, class: "btn btn-remove"
+
+ %h3.page-title
+ OAuth2
+ %fieldset.oauth-applications
+ %legend Your applications
+ %p= link_to 'New Application', new_oauth_application_path, class: 'btn btn-success'
+ %table.table.table-striped
+ %thead
+ %tr
+ %th Name
+ %th Callback URL
+ %th
+ %th
+ %tbody
+ - @applications.each do |application|
+ %tr{:id => "application_#{application.id}"}
+ %td= link_to application.name, oauth_application_path(application)
+ %td= application.redirect_uri
+ %td= link_to 'Edit', edit_oauth_application_path(application), class: 'btn btn-link btn-small'
+ %td= render 'doorkeeper/applications/delete_form', application: application
+
+ %fieldset.oauth-authorized-applications
+ %legend Your authorized applications
+ %table.table.table-striped
+ %thead
+ %tr
+ %th Name
+ %th Created At
+ %th
+ %tbody
+ - @authorized_applications.each do |application|
+ %tr{:id => "application_#{application.id}"}
+ %td= link_to application.name, oauth_application_path(application)
+ %td= application.created_at.strftime('%Y-%m-%d %H:%M:%S')
+ %td= render 'doorkeeper/authorized_applications/delete_form', application: application