Skip to content

Commit

Permalink
Merge pull request #30 from qichunren/setup
Browse files Browse the repository at this point in the history
Setup feature
  • Loading branch information
Eric-Guo authored Dec 29, 2023
2 parents 5ce4806 + 1da6317 commit 6974f5c
Show file tree
Hide file tree
Showing 16 changed files with 352 additions and 14 deletions.
30 changes: 26 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,32 @@

SSO Portal based on oauth2 id protocol

# Self-Hosting

Before proceeding with Oauth2id installation, ensure you meet the following prerequisites:

* A server with [Docker](https://www.docker.com/) installed: Oauth2id is designed to be self-hosted with Docker.
* Rails master key, which is used to decrypt the credentials file. If you don't have one, ask for it from the project maintainer.

## Docker Run

To set up Oauth2id using `docker run`, execute the following one command to start Oauth2id:

1. Select a suitable directory as your application directory, and create a directory to store the Oauth2id database file:

```
mkdir -p /opt/oauth2id/storage
```
This step makes sure that storage directory is created and owned by the current user.
2. Run the following command to start Oauth2id:
```
cd /opt/oauth2id
docker run -p 3000:3000 -d --restart always --name oauth2id --env RAILS_MASTER_KEY=YourMasterKey -v ./storage:/rails/storage ericguo/oauth2id:main
```
This command starts Oauth2id in the background, and exposes the Oauth2id web interface on port 3000. The `--env RAILS_MASTER_KEY=YourMasterKey` option is used to pass the Rails master key to the container. The `-v ./storage:/rails/storage` option is used to mount the storage directory on the host to the container. This is necessary to persist the Oauth2id database file.
# Quickly Start
Expand All @@ -29,10 +55,6 @@ docker run --env RAILS_MASTER_KEY=YourMasterKey -v ./storage:/rails/storage -it
docker push ericguo/oauth2id:main
```

# First user is admin

The first user will automatically become the admin, please ignore 500 erros as jwt token at first sign-up not via login screen.

# Dev env setup

Setup the puma-dev to support https in local.
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/home_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
class HomeController < ApplicationController
def index
redirect_to install_path if User.where(admin: true).count == 0

@applications = if current_user.present?
user_allowed_application_ids = current_user.user_allowed_applications.where(enable: true).pluck(:oauth_application_id)
Doorkeeper::Application.where(id: user_allowed_application_ids)
Expand Down
81 changes: 81 additions & 0 deletions app/controllers/install_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
class InstallController < ApplicationController
before_action :require_no_install, only: [:index, :step1, :step2, :step3]
layout 'sessions'

# GET /install
def index
end

# GET /install/step1
# Check environment
def step1
@db_adapter = ActiveRecord::Base.connection.adapter_name.downcase
@db_name = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: "primary").configuration_hash[:database]
@master_key_missing = Rails.application.credentials.key.blank?
@env_valid = !@master_key_missing
end

# GET /install/step2
# Import users data
def step2
end

# GET /install/step3
# Create admin user
def step3
if User.where(admin: true).count > 0
redirect_to install_step4_path and return
end
@new_user = User.new
end

# GET /install/step4
def step4
@initial_admin_user = User.where(admin: true).first
end

# POST /install/step1
# Just redirect to step2
def save_step1
redirect_to install_step2_path
end

# POST /install/step2
# Import users data
def save_step2
if params[:button] == "skip"
redirect_to install_step3_path
else
redirect_to install_step2_path, alert: "[Import users] feature is not available in this version" and return
if params[:file].blank?
redirect_to install_step2_path, alert: "Please select a file"
else
# begin
# User.import(params[:file])
# redirect_to install_step3_path, notice: "Users imported successfully"
# rescue => e
# redirect_to install_step2_path, alert: e.message
# end
end
end
end

# POST /install/step3
# Create admin user
def save_step3
user_params = params.require(:user).permit(:username, :password, :password_confirmation, :email)
@new_user = User.new(user_params)
@new_user.admin = true
@new_user.skip_confirmation!
if @new_user.save
redirect_to install_step4_path, notice: "Admin user created successfully"
else
render "install/step3"
end
end

private
def require_no_install
redirect_to root_path if User.where(admin: true).count > 0
end
end
9 changes: 0 additions & 9 deletions app/controllers/user/registrations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,6 @@ class User::RegistrationsController < Devise::RegistrationsController
before_action :check_signup_allowed, only: %i[new create]
layout 'sessions', only: %i[new create]

def create
super do |user|
if User.count == 1
user.admin = true
user.save
user.confirm
end
end
end

private

Expand Down
21 changes: 21 additions & 0 deletions app/views/install/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<section class="login-content">
<div class="logo">
<h1>Oauth2 Install</h1>
</div>
<div class="login-box login-box-signup">
<div class="p-4">
<h3><i class="fa fa-solid fa-gear"></i> Install</h3>
<p>Welcome to Oauth2id Software!</p>
<p>The installation steps are as follows:</p>
<ol class="list-group list-group-flush">
<li class="list-group-item">1. Check environment.</li>
<li class="list-group-item">2. Import users.</li>
<li class="list-group-item">3. Set up the administrator user.</li>
</ol>
<div class="mt-4">
<%= link_to "Next", install_step1_path, class: 'btn btn-primary btn-block' %>
</div>
</div>
</div>
</section>

31 changes: 31 additions & 0 deletions app/views/install/step1.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<section class="login-content">
<div class="logo">
<h1>Oauth2 Install</h1>
</div>
<div class="login-box login-box-signup">
<%= form_with(url: install_step1_path, method: :post, html: { class: 'p-4' }) do |f| %>
<h3><i class="fa fa-solid fa-users"></i> Check environment</h3>

<ol class="my-4">
<li>Ruby Version: <%= RUBY_VERSION %></li>
<li>Rails Version: <%= Rails.version %></li>
<li>Database: <%= @db_name %> (<%= @db_adapter %>) </li>
<% if @master_key_missing %>
<li class="text-danger">Warning: Missing RAILS MASTER KEY</li>
<% end %>
</ol>

<div class="d-flex form-group btn-container">
<% if @env_valid %>
<%= button_tag(type: 'submit', class: 'btn btn-primary flex-fill') do %>
<i class="fa fa-sign-in fa-lg fa-fw"></i> Next
<% end %>
<% else %>
<%= button_tag(type: 'submit', disabled: :disabled, class: 'btn btn-primary flex-fill') do %>
<i class="fa fa-sign-in fa-lg fa-fw"></i> Next
<% end %>
<% end %>
</div>
<% end %>
</div>
</section>
33 changes: 33 additions & 0 deletions app/views/install/step2.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<section class="login-content">
<div class="logo">
<h1>Oauth2 Install</h1>
</div>
<div class="login-box login-box-signup">
<%= form_with(model: @new_user, url: install_step2_path, method: :post, html: { class: 'p-4' }) do |f| %>
<h3><i class="fa fa-solid fa-users"></i> Import users</h3>
<div class="form-group">
<label class="control-label">CSV file</label>
<%= f.file_field :file, autofocus: true, placeholder: 'csv file', class: 'form-control' -%>
</div>

<div class="d-flex form-group btn-container">
<%= button_tag(type: 'submit', class: 'btn btn-primary flex-fill') do %>
<i class="fa fa-sign-in fa-lg fa-fw"></i> Next
<% end %>

<%= button_tag(type: 'submit', value: 'skip', class: 'ml-4 btn') do %>
<i class="fa fa-fast-forward"></i> Skip
<% end %>
</div>

<div class="mt-4">
Tips: <br>
<ul>
<li>CSV file must have header row</li>
<li>CSV file must have columns: username, email, password</li>
<li>CSV file must have at least one row</li>
<li>CSV file must be UTF-8 encoded</li>
</div>
<% end %>
</div>
</section>
46 changes: 46 additions & 0 deletions app/views/install/step3.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<section class="login-content">
<div class="logo">
<h1>Oauth2 Install</h1>
</div>
<div class="login-box login-box-signup">
<%= form_with(model: @new_user, scope: :user, url: install_step3_path, method: :post, html: { class: 'p-4' }) do |f| %>
<h3><i class="fa fa-solid fa-user"></i> Create admin user</h3>

<% if @new_user.errors.any? %>
<div class="alert alert-danger">
<ul>
<% @new_user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>

<div class="form-group">
<label class="control-label"><%= t('user.username') -%></label>
<%= f.text_field :username, autofocus: true, placeholder: t('user.username_placeholder'), class: 'form-control' -%>
</div>
<div class="form-group">
<label class="control-label"><%= t('user.email') -%></label>
<%= f.email_field :email, autocomplete: 'email', placeholder: 'Email', class: 'form-control' %>
</div>
<div class="form-group">
<label class="control-label"><%= t('user.password') -%>
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> <%= t('user.characters_minimum') -%>)</em><br />
<% end %>
</label>
<%= f.password_field :password, autocomplete: 'off', class: 'form-control' %>
</div>
<div class="form-group">
<label class="control-label"><%= t('user.password_confirmation') -%></label>
<%= f.password_field :password_confirmation, autocomplete: 'off', class: 'form-control' %>
</div>
<div class="d-flex form-group btn-container">
<%= button_tag(type: 'submit', class: 'btn btn-primary flex-fill') do %>
<i class="fa fa-sign-in fa-lg fa-fw"></i> Next
<% end %>
</div>
<% end %>
</div>
</section>
22 changes: 22 additions & 0 deletions app/views/install/step4.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<section class="login-content">
<div class="logo">
<h1>Oauth2 Install</h1>
</div>
<div class="login-box login-box-signup">
<div class="p-4">
<h3><i class="fa fa-solid fa-check"></i> Install successful!</h3>
<p>Congratulations, your installation was successful!</p>
<p>The initial admin user: </p>
<ol class="list-group list-group-flush">
<li class="list-group-item">Email: <strong><%= @initial_admin_user.email %></strong></li>
<li class="list-group-item">Username: <strong><%= @initial_admin_user.username %></strong></li>
</ol>
<div class="mt-4">
<%= link_to new_user_session_path, class: 'btn btn-primary btn-block' do -%>
<i class="fa fa-sign-in fa-lg fa-fw"></i> Login
<% end %>
</div>
</div>
</div>
</section>

1 change: 1 addition & 0 deletions config/credentials/test.key
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3b7e27951a6b87e750abdaec2d4b85d4
Loading

0 comments on commit 6974f5c

Please sign in to comment.