Compare commits
10 Commits
1a2482434c
...
6d20ac9a1c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d20ac9a1c
|
||
|
|
27dd4163f0
|
||
|
|
1a55e5e895
|
||
|
|
8eb487600c
|
||
|
|
678e80a25d
|
||
|
|
30fb9805e5
|
||
|
|
e675970f4c
|
||
|
|
a0727e709f
|
||
|
|
55abbcc5ad
|
||
|
|
ffed398024
|
@@ -7,16 +7,30 @@
|
||||
@apply text-left;
|
||||
}
|
||||
|
||||
table th {
|
||||
table thead th {
|
||||
@apply pb-3.5 text-sm font-normal uppercase text-gray-500;
|
||||
}
|
||||
|
||||
table tbody th {
|
||||
@apply text-left font-normal text-gray-500;
|
||||
}
|
||||
|
||||
table th:not(:last-of-type),
|
||||
table td:not(:last-of-type) {
|
||||
@apply pr-2;
|
||||
}
|
||||
|
||||
table td {
|
||||
table td, tbody th {
|
||||
@apply py-2;
|
||||
}
|
||||
|
||||
table.divided {
|
||||
@apply divide-y divide-gray-300;
|
||||
}
|
||||
table.divided tbody {
|
||||
@apply divide-y divide-gray-200;
|
||||
}
|
||||
table.divided td, table.divided tbody th {
|
||||
@apply py-3;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,32 @@
|
||||
class Admin::UsersController < Admin::BaseController
|
||||
before_action :set_user, only: [:show]
|
||||
before_action :set_current_section
|
||||
|
||||
def index
|
||||
ldap = LdapService.new
|
||||
@ou = params[:ou] || "kosmos.org"
|
||||
@orgs = ldap.fetch_organizations
|
||||
@entries = ldap.fetch_users(ou: @ou)
|
||||
ldap = LdapService.new
|
||||
@ou = params[:ou] || "kosmos.org"
|
||||
@orgs = ldap.fetch_organizations
|
||||
@users = User.where(ou: @ou).order(cn: :asc).to_a
|
||||
|
||||
@stats = {
|
||||
users_confirmed: User.where(ou: @ou).confirmed.count,
|
||||
users_pending: User.where(ou: @ou).pending.count
|
||||
}
|
||||
end
|
||||
|
||||
def show
|
||||
if Setting.lndhub_admin_enabled?
|
||||
@lndhub_user = @user.lndhub_user
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_user
|
||||
address = params[:address].split("@")
|
||||
@user = User.where(cn: address.first, ou: address.last).first
|
||||
end
|
||||
|
||||
def set_current_section
|
||||
@current_section = :users
|
||||
end
|
||||
|
||||
@@ -10,5 +10,12 @@ module ApplicationHelper
|
||||
"text-gray-300 hover:bg-gray-900/30 hover:text-white active:bg-gray-900/30 active:text-white px-3 py-2 rounded-md font-medium text-base md:text-sm block md:inline-block"
|
||||
end
|
||||
end
|
||||
|
||||
# Colors available: gray, red, yellow, green, blue, purple, pink
|
||||
# (Add more colors by adding classes to the safelist in tailwind.config.js)
|
||||
def badge(text, color)
|
||||
tag.span text, class: "inline-flex items-center rounded-full bg-#{color}-100 px-2.5 py-0.5 text-xs font-medium text-#{color}-800"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
class Invitation < ApplicationRecord
|
||||
# Relations
|
||||
belongs_to :user
|
||||
belongs_to :invitee, class_name: "User", foreign_key: 'invited_user_id', optional: true
|
||||
|
||||
# Validations
|
||||
validates_presence_of :user
|
||||
|
||||
@@ -10,6 +10,18 @@ class LndhubUser < LndhubBase
|
||||
foreign_key: "login"
|
||||
|
||||
def balance
|
||||
accounts.current.first.ledgers.sum("account_ledgers.amount")
|
||||
accounts.current.first.ledgers.sum("account_ledgers.amount").to_i.abs
|
||||
end
|
||||
|
||||
def sum_outgoing
|
||||
accounts.outgoing.first.ledgers.sum("account_ledgers.amount").to_i.abs
|
||||
end
|
||||
|
||||
def sum_incoming
|
||||
accounts.incoming.first.ledgers.sum("account_ledgers.amount").to_i.abs
|
||||
end
|
||||
|
||||
def sum_fees
|
||||
accounts.fees.first.ledgers.sum("account_ledgers.amount").to_i.abs
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,6 +3,10 @@ class User < ApplicationRecord
|
||||
|
||||
# Relations
|
||||
has_many :invitations, dependent: :destroy
|
||||
has_one :invitation, inverse_of: :invitee, foreign_key: 'invited_user_id'
|
||||
has_one :inviter, through: :invitation, source: :user
|
||||
has_many :invitees, through: :invitations
|
||||
|
||||
has_many :donations, dependent: :nullify
|
||||
|
||||
has_one :lndhub_user, class_name: "LndhubUser", inverse_of: "user",
|
||||
@@ -66,6 +70,12 @@ class User < ApplicationRecord
|
||||
end
|
||||
end
|
||||
|
||||
def ldap_entry
|
||||
return @ldap_entry if defined?(@ldap_entry)
|
||||
ldap = LdapService.new
|
||||
@ldap_entry = ldap.fetch_users(uid: self.cn, ou: self.ou).first
|
||||
end
|
||||
|
||||
def address
|
||||
"#{self.cn}@#{self.ou}"
|
||||
end
|
||||
|
||||
@@ -43,7 +43,7 @@ class LdapService < ApplicationService
|
||||
end
|
||||
|
||||
attributes = %w{dn cn uid mail admin}
|
||||
filter = Net::LDAP::Filter.eq("uid", "*")
|
||||
filter = Net::LDAP::Filter.eq("uid", args[:uid] || "*")
|
||||
|
||||
entries = ldap_client.search(base: treebase, filter: filter, attributes: attributes)
|
||||
entries.sort_by! { |e| e.cn[0] }
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<section>
|
||||
<% if @donations.any? %>
|
||||
<h3>Recent Donations</h3>
|
||||
<table>
|
||||
<table class="divided">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>User</th>
|
||||
@@ -33,11 +33,10 @@
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<% @donations.each do |donation| %>
|
||||
<tr>
|
||||
<td><%= donation.user.address %></td>
|
||||
<td><%= link_to donation.user.address, admin_user_path(donation.user.address), class: 'ks-text-link' %></td>
|
||||
<td class="text-right"><%= sats_to_btc donation.amount_sats %></td>
|
||||
<td class="text-right"><% if donation.amount_eur.present? %><%= number_to_currency donation.amount_eur / 100, unit: "" %><% end %></td>
|
||||
<td class="text-right"><% if donation.amount_usd.present? %><%= number_to_currency donation.amount_usd / 100, unit: "" %><% end %></td>
|
||||
|
||||
@@ -1,35 +1,34 @@
|
||||
<%= render HeaderComponent.new(title: "Donations") %>
|
||||
|
||||
<%= render MainSimpleComponent.new do %>
|
||||
<p>
|
||||
<strong>User:</strong>
|
||||
<%= @donation.user.address %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Amount sats:</strong>
|
||||
<%= @donation.amount_sats %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Amount eur:</strong>
|
||||
<%= @donation.amount_eur %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Amount usd:</strong>
|
||||
<%= @donation.amount_usd %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Public name:</strong>
|
||||
<%= @donation.public_name %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<strong>Date:</strong>
|
||||
<%= @donation.paid_at %>
|
||||
</p>
|
||||
<table class="w-1/2">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>User</th>
|
||||
<td><%= link_to @donation.user.address, admin_user_path(@donation.user.address), class: 'ks-text-link' %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Amount sats</th>
|
||||
<td><%= @donation.amount_sats %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Amount EUR</th>
|
||||
<td><%= @donation.amount_eur %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Amount USD</th>
|
||||
<td><%= @donation.amount_usd %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Public name</th>
|
||||
<td><%= @donation.public_name %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<td><%= @donation.paid_at.strftime("%Y-%m-%d (%H:%M UTC)") %></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p class="mt-8">
|
||||
<%= link_to 'Edit', edit_admin_donation_path(@donation), class: 'ks-text-link' %> |
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
<% if @invitations_used.any? %>
|
||||
<section>
|
||||
<h3>Recently Accepted</h3>
|
||||
<table>
|
||||
<table class="divided">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Token</th>
|
||||
@@ -38,8 +38,8 @@
|
||||
<tr>
|
||||
<td class="overflow-ellipsis font-mono"><%= invitation.token %></td>
|
||||
<td><%= invitation.used_at.strftime("%Y-%m-%d (%H:%M UTC)") %></td>
|
||||
<td><%= invitation.user.address %></td>
|
||||
<td><%= User.find(invitation.invited_user_id).address %></td>
|
||||
<td><%= link_to invitation.user.address, admin_user_path(invitation.user.address), class: "ks-text-link" %></td>
|
||||
<td><%= link_to invitation.invitee.address, admin_user_path(invitation.invitee.address), class: "ks-text-link" %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
<section>
|
||||
<h3>Accounts</h3>
|
||||
<table>
|
||||
<table class="divided">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>LN Account</th>
|
||||
@@ -36,7 +36,7 @@
|
||||
</td>
|
||||
<td>
|
||||
<% if user = @users.find{ |u| u[2] == account.login } %>
|
||||
<%= "#{user[0]}@#{user[1]}" %>
|
||||
<%= link_to "#{user[0]}@#{user[1]}", admin_user_path("#{user[0]}@#{user[1]}"), class: "ks-text-link" %>
|
||||
<% end %>
|
||||
</td>
|
||||
<td><%= number_with_delimiter account.balance.to_i.to_s %></td>
|
||||
|
||||
@@ -30,22 +30,21 @@
|
||||
<% end %>
|
||||
|
||||
<section>
|
||||
<table>
|
||||
<table class="divided">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>UID</th>
|
||||
<th>E-Mail</th>
|
||||
<th>Admin</th>
|
||||
<th>Status</th>
|
||||
<th>Roles</th>
|
||||
<!-- <th>Password</th> -->
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<% @entries.each do |entry| %>
|
||||
<% @users.each do |user| %>
|
||||
<tr>
|
||||
<td><%= entry[:uid] %></td>
|
||||
<td><%= entry[:mail] %></td>
|
||||
<td><%= entry[:admin] %></td>
|
||||
<!-- <td><%= entry[:password] %></td> -->
|
||||
<td><%= link_to(user.cn, admin_user_path(user.address), class: 'ks-text-link') %></td>
|
||||
<td><%= user.confirmed_at.nil? ? badge("pending", :yellow) : "" %></td>
|
||||
<td><%= user.is_admin? ? badge("admin", :red) : "" %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
|
||||
89
app/views/admin/users/show.html.erb
Normal file
89
app/views/admin/users/show.html.erb
Normal file
@@ -0,0 +1,89 @@
|
||||
<%= render HeaderComponent.new(title: "User: #{@user.address}") %>
|
||||
|
||||
<%= render MainSimpleComponent.new do %>
|
||||
<section>
|
||||
<h3>Account</h3>
|
||||
<table class="w-1/2 divided">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>Created at</th>
|
||||
<td><%= @user.created_at.strftime("%Y-%m-%d (%H:%M UTC)") %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Confirmed at</th>
|
||||
<td>
|
||||
<% if @user.confirmed_at %>
|
||||
<%= @user.confirmed_at.strftime("%Y-%m-%d (%H:%M UTC)") %>
|
||||
<% else %>
|
||||
<%= badge "pending", :yellow %>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Email</th>
|
||||
<td><%= @user.email %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Roles</th>
|
||||
<td><%= @user.is_admin? ? badge("admin", :red) : "—" %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Invited by</th>
|
||||
<td>
|
||||
<% if @user.inviter %>
|
||||
<%= link_to @user.inviter.address, admin_user_path(@user.inviter.address), class: 'ks-text-link' %>
|
||||
<% else %>—<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Invitations available</th>
|
||||
<td>
|
||||
<%= @user.invitations.count %>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th class="align-top">Invited users</th>
|
||||
<td class="align-top">
|
||||
<% if @user.invitees.length > 0 %>
|
||||
<ul class="mb-0">
|
||||
<% @user.invitees.order(cn: :asc).each do |invitee| %>
|
||||
<li class="leading-none mb-2 last:mb-0"><%= link_to invitee.address, admin_user_path(invitee.address), class: 'ks-text-link' %></li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% else %>—<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
|
||||
<% if Setting.lndhub_admin_enabled? %>
|
||||
<section>
|
||||
<h3>LndHub</h3>
|
||||
<% if @lndhub_user %>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Account</th>
|
||||
<th>Balance</th>
|
||||
<th>Incoming</th>
|
||||
<th>Outgoing</th>
|
||||
<th>Fees</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><%= @user.ln_account %></td>
|
||||
<td><%= number_with_delimiter @lndhub_user.balance %> sats</td>
|
||||
<td><%= number_with_delimiter @lndhub_user.sum_incoming %> sats</td>
|
||||
<td><%= number_with_delimiter @lndhub_user.sum_outgoing %> sats</td>
|
||||
<td><%= number_with_delimiter @lndhub_user.sum_fees %> sats</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<% else %>
|
||||
<p>No LndHub user found for account <strong class="font-mono"><%= @user.ln_account %></strong>.
|
||||
<% end %>
|
||||
</section>
|
||||
<% end %>
|
||||
<% end %>
|
||||
@@ -39,7 +39,7 @@ Rails.application.routes.draw do
|
||||
|
||||
namespace :admin do
|
||||
root to: 'dashboard#index'
|
||||
resources 'users', only: ['index']
|
||||
resources 'users', param: 'address', only: ['index', 'show'], constraints: { address: /.*/ }
|
||||
get 'invitations', to: 'invitations#index'
|
||||
resources :donations
|
||||
get 'lightning', to: 'lightning#index'
|
||||
|
||||
@@ -7,6 +7,15 @@ module.exports = {
|
||||
'./app/helpers/**/*.rb',
|
||||
'./app/javascript/**/*.js'
|
||||
],
|
||||
safelist: [
|
||||
'bg-gray-100', 'text-gray-800',
|
||||
'bg-red-100', 'text-red-800',
|
||||
'bg-yellow-100', 'text-yellow-800',
|
||||
'bg-green-100', 'text-green-800',
|
||||
'bg-blue-100', 'text-blue-800',
|
||||
'bg-purple-100', 'text-purple-800',
|
||||
'bg-pink-100', 'text-pink-800',
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
@@ -16,5 +25,5 @@ module.exports = {
|
||||
},
|
||||
plugins: [
|
||||
require('@tailwindcss/forms')
|
||||
],
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user