Exec=/usr/bin/google-chrome-stable --gtk-version=3 %U
Exec=/usr/bin/google-chrome-stable --incognito --gtk-version=3
【書き換え】
select Fxxxx,replace( Fxxxx,'D:','C:') from Schema.Table
where Fxxxx like 'D:\%'
update Schema.Table set Fxxx = replace(Fxxxx,'D:','C:')
where Fxxxx like 'D:\%'
【email マスク】
SELECT
email,
LOWER(
LEFT(account_part, 1) ||
REPEAT('*', GREATEST(LENGTH(account_part) - 2, 1)) ||
RIGHT(account_part, 1) ||'@' || domain_part
) AS masked_email
FROM (
SELECT
email,
SPLIT_PART(email, '@', 1) AS account_part,
SPLIT_PART(email, '@', 2) AS domain_part
FROM service."Users_user"
) AS sub;
UPDATE "Users_user"
SET email = LOWER(
LEFT(account_part, 1) ||
REPEAT('*', GREATEST(LENGTH(account_part) - 2, 1)) ||
RIGHT(account_part, 1) ||
'@' || domain_part
)
FROM (
SELECT
uuid, -- 主キー
SPLIT_PART(email, '@', 1) AS account_part,
SPLIT_PART(email, '@', 2) AS domain_part
FROM ”Users_user"
) AS sub
WHERE "Users_User".uuid = sub.uuid;
① バックアップ列 email_original を作成
ALTER TABLE "Users_User"
ADD COLUMN email_original TEXT;
② 元の email を email_original にコピーしてからマスキング
UPDATE "Users_User"
SET
email_original = email,
email = LOWER(
LEFT(account_part, 1) ||
REPEAT('*', GREATEST(LENGTH(account_part) - 2, 1)) ||
RIGHT(account_part, 1) ||
'@' || domain_part
)
FROM (
SELECT
uuid,
SPLIT_PART(email, '@', 1) AS account_part,
SPLIT_PART(email, '@', 2) AS domain_part
FROM "Users_User"
) AS sub
WHERE "Users_User".id = sub.id;
【氏名】
SELECT
first_name,
CASE
WHEN LENGTH(first_name) <= 2 THEN
SUBSTRING(first_name, 1, 1) || REPEAT('*', LENGTH(first_name) - 1)
ELSE
SUBSTRING(first_name, 1, 1) ||
REPEAT('*', LENGTH(first_name) - 2) ||
SUBSTRING(first_name, LENGTH(first_name), 1)
END AS masked_name
FROM service."Users_user";
UPDATE "Users_user"
SET first_name = CASE
WHEN LENGTH(first_name) <= 2 THEN
SUBSTRING(first_name, 1, 1) || REPEAT('*', LENGTH(first_name) - 1)
ELSE
SUBSTRING(first_name, 1, 1) ||
REPEAT('*', LENGTH(first_name) - 2) ||
SUBSTRING(full_name, LENGTH(first_name), 1)
END;
【電話】
SELECT
tel,
CASE
WHEN LENGTH(tel) >= 11 THEN
SUBSTRING(tel, 1, 3) ||
REPEAT('*', LENGTH(tel) - 7) ||
SUBSTRING(tel, LENGTH(tel) - 3, 4)
ELSE
tel
END AS masked_tel
FROM "Users_user";
UPDATE "Users_user"
SET tel =
CASE
WHEN LENGTH(tel) >= 11 THEN
SUBSTRING(tel, 1, 3) ||
REPEAT('*', LENGTH(tel) - 7) ||
SUBSTRING(tel, LENGTH(tel) - 3, 4)
ELSE
tel
END;
(ハイフンなしをハイフォン付きで表示)
SELECT
tel,
CASE
WHEN tel ~ '^\+81\d{9,10}$' THEN
-- +81xxx-xxxx-xxxx の形式に変換(+81から始まる場合)
'+81-' || SUBSTRING(tel, 4, 1) || '-' ||
SUBSTRING(tel, 5, 4) || '-' ||
SUBSTRING(tel, 9, 4)
WHEN LENGTH(tel) = 11 THEN
-- 09012345678 を 090-1234-5678 の形式に変換
SUBSTRING(tel, 1, 3) || '-' ||
SUBSTRING(tel, 4, 4) || '-' ||
SUBSTRING(tel, 8, 4)
WHEN LENGTH(tel) = 10 THEN
-- 03-1234-5678 のような10桁の番号に対応
SUBSTRING(tel, 1, 2) || '-' ||
SUBSTRING(tel, 3, 4) || '-' ||
SUBSTRING(tel, 7, 4)
ELSE
tel -- それ以外はそのまま表示
END AS formatted_tel
FROM "Users_User";
【住所】
SELECT
address,
CASE
WHEN address ~ '^.{3,}' THEN
SUBSTRING(address, 1, 3) || REPEAT('*', LENGTH(address) - 3)
ELSE
address
END AS masked_address
FROM "Users_User";
UPDATE "Users_User"
SET address = CASE
WHEN address ~ '^.{3,}' THEN
SUBSTRING(address, 1, 3) || REPEAT('*', LENGTH(address) - 3)
ELSE
address
END;
【秘密情報らしいフィールドの検索】
SELECT
table_schema,
table_name,
column_name,
data_type
FROM
information_schema.columns
WHERE
column_name ILIKE ANY (
ARRAY[
'%name%', -- 氏名, full_name, last_name, etc
'%email%', -- email, e_mail
'%tel%', -- tel, telephone, tel_no
'%phone%', -- phone_number
'%address%' -- address, home_address
]
)
AND table_schema NOT IN ('pg_catalog', 'information_schema')
ORDER BY
table_schema, table_name;
-- 例: Users_User テーブルの full_name をマスクするSQLを出力
SELECT
'UPDATE "' || table_name || '" SET "' || column_name || '" = ' ||
CASE
WHEN column_name ILIKE '%name%' THEN
'CASE WHEN LENGTH("' || column_name || '") >= 3 THEN ' ||
'SUBSTRING("' || column_name || '", 1, 1) || REPEAT(''*'', LENGTH("' || column_name || '") - 2) || ' ||
'SUBSTRING("' || column_name || '", LENGTH("' || column_name || '"), 1) ELSE "' || column_name || '" END'
WHEN column_name ILIKE '%email%' THEN
'CASE WHEN POSITION(''@'' IN "' || column_name || '") > 2 THEN ' ||
'SUBSTRING("' || column_name || '", 1, 1) || REPEAT(''*'', POSITION(''@'' IN "' || column_name || '") - 2) || ' ||
'SUBSTRING("' || column_name || '", POSITION(''@'' IN "' || column_name || '") - 1) ELSE "' || column_name || '" END'
WHEN column_name ILIKE '%tel%' OR column_name ILIKE '%phone%' THEN
'CASE WHEN LENGTH("' || column_name || '") >= 11 THEN ' ||
'SUBSTRING("' || column_name || '", 1, 3) || ''-****-'' || SUBSTRING("' || column_name || '", 8, 4) ELSE "' || column_name || '" END'
WHEN column_name ILIKE '%address%' THEN
'CASE WHEN LENGTH("' || column_name || '") > 3 THEN ' ||
'SUBSTRING("' || column_name || '", 1, 3) || REPEAT(''*'', LENGTH("' || column_name || '") - 3) ELSE "' || column_name || '" END'
ELSE
'"' || column_name || '"'
END || ';'
AS mask_sql
FROM information_schema.columns
WHERE
column_name ILIKE ANY (
ARRAY['%name%', '%email%', '%tel%', '%phone%', '%address%']
)
AND table_schema = 'public' -- 必要なら変更
ORDER BY table_name, column_name;
【パーティション】
SET search_path TO pg_catalog, public
explain analyze
WITH latest_rdate AS (
SELECT
MAX(rdate) AS rdate
FROM arcsdbss.ssr002
WHERE
--rdate BETWEEN '20250401' AND '20250431'
pg_catalog.to_date(rdate::text, 'YYYYMMDD'::text) BETWEEN DATE '2025-04-01' AND DATE '2025-04-30'
AND gcode = '101'
AND ccode = '8544'
AND scode IN ('0000', '0001', '0003')
AND rcode = '0000000000000'
AND ztime <> '999999'
)
SELECT
a.rdate,
a.ztime
FROM arcsdbss.ssr002 a
where
a.rdate = (SELECT rdate FROM latest_rdate) and
gcode='101' and
ccode='8544' and
scode in ('0000','0001','0003') and
rcode='0000000000000';
#-----------------------------------------------------------------------------------------
ALTER TABLE ssr002_part_subp202504_0 SET (autovacuum_vacuum_scale_factor = 0.1);
ALTER TABLE ssr002_part_subp202504_1 SET (autovacuum_vacuum_scale_factor = 0.1);
ALTER TABLE ssr002_part_subp202504_2 SET (autovacuum_vacuum_scale_factor = 0.1);
ALTER TABLE ssr002_part_subp202504_3 SET (autovacuum_vacuum_scale_factor = 0.1);
ALTER TABLE ssr002_part_subp202504_4 SET (autovacuum_vacuum_scale_factor = 0.1);
ALTER TABLE ssr002_part_subp202504_5 SET (autovacuum_vacuum_scale_factor = 0.1);
ALTER TABLE ssr002_part_subp202504_6 SET (autovacuum_vacuum_scale_factor = 0.1);
ALTER TABLE ssr002_part_subp202504_7 SET (autovacuum_vacuum_scale_factor = 0.1);
SELECT
n.nspname AS schema,
c.relname AS table_name,
pg_catalog.array_to_string(c.reloptions, ', ') AS reloptions
FROM
pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE
c.relname LIKE 'ssr002_part_subp202504_%'
AND c.relkind = 'r';
Djangoでdjango-otpを使用して新たにQRコードを生成し、二要素認証を実装する方法について説明します。
1. 必要なパッケージのインストール
まず、以下のパッケージをインストールします。
bash
コピーする
編集する
pip install django-otp qrcode[pil]
django-otpはワンタイムパスワードのサポートを追加し、qrcodeはQRコードの生成に使用します。
2. Djangoプロジェクトの設定
settings.pyにdjango_otpとdjango_otp.plugins.otp_totpを追加します。
python
コピーする
編集する
INSTALLED_APPS = [
# 既存のアプリケーション
'django_otp',
'django_otp.plugins.otp_totp',
]
これにより、TOTP(Time-based One-Time Password)のサポートが有効になります。
3. モデルの作成
ユーザーごとにTOTPデバイスを管理するため、TOTPDeviceモデルを作成します。
python
コピーする
編集する
from django_otp.plugins.otp_totp.models import TOTPDevice
# ユーザーに関連付けられたTOTPデバイスを作成
device = TOTPDevice.objects.create(user=user)
TOTPDeviceは、ユーザーごとに一意のシークレットキーを生成し、QRコードの生成に使用されます。
4. QRコードの生成
qrcodeライブラリを使用して、生成されたシークレットキーからQRコードを作成します。
python
コピーする
編集する
import qrcode
from io import BytesIO
from base64 import b64encode
# デバイスの設定URLを取得
config_url = device.config_url
# QRコードを生成
qr = qrcode.QRCode()
qr.add_data(config_url)
qr.make(fit=True)
# 画像をメモリに保存
img = qr.make_image(fill='black', back_color='white')
buffer = BytesIO()
img.save(buffer, format='PNG')
buffer.seek(0)
# 画像をBase64でエンコード
img_str = b64encode(buffer.getvalue()).decode()
このコードにより、QRコードの画像データがBase64形式でエンコードされ、テンプレートで表示可能になります。
5. テンプレートでの表示
生成したQRコードをテンプレートで表示するには、以下のようにします。
html
コピーする
編集する
<img src="data:image/png;base64,{{ img_str }}" alt="QR Code">
これにより、ユーザーはQRコードをスキャンして認証アプリに追加できます。
6. 認証の検証
ユーザーが認証アプリで生成したトークンを入力した際に、それを検証する必要があります。
python
コピーする
編集する
# ユーザーのデバイスを取得
device = TOTPDevice.objects.get(user=user)
# トークンの検証
if device.verify_token(token):
# 認証成功
...
else:
# 認証失敗
...
verify_tokenメソッドは、ユーザーが入力したトークンが正しいかどうかを確認します。
参考資料
Django OTP TOTP - how to display QR code in template
django-otp 公式ドキュメント
Djangoで、二要素認証を、Google認証システムを使って実装。
pyotpでワンタイムパスワードを試してみる
Custom Two-factor with Qrcode in django
【Django】django-otpで多要素認証(二要素認証)を実現させる
$vi cmd __EOF__
#!/bin/bash
while IFS= read -r ip; do
if [[ -n "$ip" ]]; then
# whois コマンドで CustName を取得
cust_name=$(whois "$ip" | grep -i 'CustName' | awk -F: '{print $2}' | xargs)
# CustName が見つからない場合、OrgName を試す
if [[ -z "$cust_name" ]]; then
cust_name=$(whois "$ip" | grep -i 'OrgName' | awk -F: '{print $2}' | xargs)
fi
# CustName が見つからない場合、descr を試す
if [[ -z "$cust_name" ]]; then
cust_name=$(whois "$ip" | grep -i 'descr' | head -n 1 | awk -F: '{print $2}' | xargs)
fi
echo "$ip, $cust_name"
fi
done
__EOF__
chmod a+x cmd
cat /var/log/httpd/access_log* |grep "GET /office/cti"|cut -d" " -f 1|sort|uniq||.cmd
$ xinput --get-button-map 12
device has no buttons
[takahab@rocky92 ~]$ xinput list
⎡ Virtual core pointer id=2 [master pointer (3)]
⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]
⎜ ↳ 2.4G Mouse Consumer Control id=9 [slave pointer (2)]
⎜ ↳ ELECOM IST TrackBall Mouse id=11 [slave pointer (2)]
⎜ ↳ 2.4G Mouse id=14 [slave pointer (2)]
⎜ ↳ ELECOM IST TrackBall Consumer Control id=15 [slave pointer (2)]
⎜ ↳ Getech HUGE TrackBall id=18 [slave pointer (2)]
⎣ Virtual core keyboard id=3 [master keyboard (2)]
↳ Virtual core XTEST keyboard id=5 [slave keyboard (3)]
↳ Power Button id=6 [slave keyboard (3)]
↳ Video Bus id=7 [slave keyboard (3)]
↳ Power Button id=8 [slave keyboard (3)]
↳ 2.4G Mouse Consumer Control id=10 [slave keyboard (3)]
↳ ELECOM IST TrackBall System Control id=12 [slave keyboard (3)]
↳ 2.4G Mouse id=13 [slave keyboard (3)]
↳ ELECOM IST TrackBall Consumer Control id=16 [slave keyboard (3)]
↳ 2.4G Mouse System Control id=17 [slave keyboard (3)]
↳ Getech HUGE TrackBall id=19 [slave keyboard (3)]
[takahab@rocky92 ~]$ xinput --get-button-map 11
1 2 3 4 5 6 7 8 9
[takahab@rocky92 ~]$ xinput query-state 11
2 classes :
ButtonClass
button[1]=up
button[2]=up
button[3]=up
button[4]=up
button[5]=up
button[6]=up
button[7]=up
button[8]=up
button[9]=up
ValuatorClass Mode=Relative Proximity=In
valuator[0]=4918
valuator[1]=2589
valuator[2]=0
valuator[3]=-15
[takahab@rocky92 ~]$
vi /usr/share/applications/google-chrome.desktop Exec=/usr/bin/google-chrome-stable --gtk-version=3 %U Exec=/usr/bin/google-chrome-stable ...