Auto Update

This commit is contained in:
砍砍
2023-12-26 21:03:56 +08:00
parent d76d4cde32
commit f0a18bace1
10 changed files with 209 additions and 105 deletions

7
.gitignore vendored
View File

@@ -54,3 +54,10 @@ build-iPhoneSimulator/
# Used by RuboCop. Remote config files pulled in from inherit_from directive.
# .rubocop-https?--*
temp/
output/
license_key
license_key.pub
result.gitlab-license
features.list

0
.root Normal file
View File

49
feature.scan.py Executable file
View File

@@ -0,0 +1,49 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import re
import os
import sys
SCANNING_DIR = sys.argv[1]
OUTPUT_LIST_FILE = sys.argv[2]
print(f"[*] scanning directory: {SCANNING_DIR}")
# use regex to find the string
# eg ::License.feature_available?(:aaa) || ::Feature.enabled?(:bbb, self)
# make sure +? for shortest match
REGEX_PARTTERN = "License.feature_available\?\(:.+?\)"
REQUIRED_FILE_SUFFIX = ['rb']
scanning_file_list = set()
def build_file_list(input: str):
global scanning_file_list
scanning_file_list.add(input)
if os.path.isdir(input):
for file in os.listdir(input):
build_file_list(os.path.join(input, file))
build_file_list(SCANNING_DIR)
print(f"[*] scanning {len(scanning_file_list)} files...")
feature_list=set()
for file in scanning_file_list:
if not os.path.isfile(file): continue
if not file.split(".")[-1] in REQUIRED_FILE_SUFFIX: continue
with open(file, "r") as f:
content = f.read()
all_match = re.findall(REGEX_PARTTERN, content)
all_match = [x.split(":")[1].split(")")[0] for x in all_match]
all_match = [x for x in all_match if x]
feature_list.update(all_match)
print(f"[*] found {len(feature_list)} features")
feature_list = list(feature_list)
feature_list.sort()
print(f"[*] writing to {OUTPUT_LIST_FILE}...")
with open(OUTPUT_LIST_FILE, "w") as f:
for feature in feature_list:
f.write(feature + "\n")
print(f"[*] done")

View File

@@ -1,31 +1,47 @@
# GitLab License Generator
#!/usr/bin/env ruby
# encoding: utf-8
require 'openssl'
require_relative 'lib/license.rb'
puts "[i] lib gitlab-license: #{Gitlab::License::VERSION}"
OUTPUT_DIR = ARGV[0]
puts "[*] output dir: #{OUTPUT_DIR}"
LICENSE_TARGET_PRIVATE_KEY = "license_key"
LICENSE_TARGET_PUBLIC_KEY = "license_key.pub"
TARGET_LICENSE_FILE = 'result.gitlab-license'
TARGET_PLAIN_LICENSE_FILE = 'result.gitlab-license.json'
puts "[*] Booting generator"
FEATURE_LIST = []
if ARGV[1].nil?
puts "[i] you can provide a list of feature to be enabled inside license"
else
FEATURE_LIST_FILE = ARGV[1]
File.open(FEATURE_LIST_FILE).each do |line|
FEATURE_LIST.push(line.chomp)
end
FEATURE_LIST.uniq!
end
puts "[*] loaded #{FEATURE_LIST.length} features"
require 'openssl'
require_relative 'lib/license.rb'
CORE_LIB_VERSION = '2.2.1'
puts "[i] Using core library version #{CORE_LIB_VERSION}"
Dir.chdir(OUTPUT_DIR)
puts "[*] switching working dir: #{Dir.pwd}"
puts "[*] generating license..."
if !File.exist?(LICENSE_TARGET_PRIVATE_KEY) || !File.exist?(LICENSE_TARGET_PUBLIC_KEY)
puts "[*] Generating RSA keys..."
puts "[*] generating rsa key pair..."
key = OpenSSL::PKey::RSA.new(2048)
File.write(LICENSE_TARGET_PRIVATE_KEY, key.to_pem)
File.write(LICENSE_TARGET_PUBLIC_KEY, key.public_key.to_pem)
end
puts "[*] Loading RSA keys..."
puts "[*] loading key pair..."
public_key = OpenSSL::PKey::RSA.new File.read(LICENSE_TARGET_PUBLIC_KEY)
private_key = OpenSSL::PKey::RSA.new File.read(LICENSE_TARGET_PRIVATE_KEY)
puts "[*] Building license..."
puts "[*] building license..."
Gitlab::License.encryption_key = private_key
@@ -59,20 +75,17 @@ license.restrictions = {
# required, just dont overflow
}
puts "[*] Calling export..."
if !license.valid?
puts "[E] license validation failed!"
puts "[E] #{license.errors}"
exit 1
end
puts ""
puts "====================================================="
puts "[*] exporting license file..."
puts JSON.pretty_generate(JSON.parse(license.to_json))
puts "====================================================="
File.open(TARGET_PLAIN_LICENSE_FILE, "w") { |f| f.write(JSON.pretty_generate(JSON.parse(license.to_json))) }
data = license.export
File.open(TARGET_LICENSE_FILE, "w") { |f| f.write(data) }
puts "====================================================="
puts ""
puts "[*] License generated successfully!"
puts "[*] License file: #{TARGET_LICENSE_FILE}"
puts "[*] done"

View File

@@ -15,6 +15,7 @@ module Gitlab
class << self
attr_reader :encryption_key
attr_reader :fallback_decryption_keys
@encryption_key = nil
def encryption_key=(key)
@@ -24,6 +25,19 @@ module Gitlab
@encryptor = nil
end
def fallback_decryption_keys=(keys)
unless keys
@fallback_decryption_keys = nil
return
end
unless keys.is_a?(Enumerable) && keys.all? { |key| key.is_a?(OpenSSL::PKey::RSA) }
raise ArgumentError, 'Invalid fallback RSA encryption keys provided.'
end
@fallback_decryption_keys = Array(keys)
end
def encryptor
@encryptor ||= Encryptor.new(encryption_key)
end
@@ -33,11 +47,7 @@ module Gitlab
data = Boundary.remove_boundary(data)
begin
license_json = encryptor.decrypt(data)
rescue Encryptor::Error
raise ImportError, 'License data could not be decrypted.'
end
license_json = decrypt_with_fallback_keys(data)
begin
attributes = JSON.parse(license_json)
@@ -47,6 +57,20 @@ module Gitlab
new(attributes)
end
def decrypt_with_fallback_keys(data)
keys_to_try = Array(encryption_key)
keys_to_try += fallback_decryption_keys if fallback_decryption_keys
keys_to_try.each do |decryption_key|
decryptor = Encryptor.new(decryption_key)
return decryptor.decrypt(data)
rescue Encryptor::Error
next
end
raise ImportError, 'License data could not be decrypted.'
end
end
attr_reader :version
@@ -54,7 +78,8 @@ module Gitlab
:notify_users_at, :block_changes_at, :last_synced_at, :next_sync_at,
:activated_at, :restrictions, :cloud_licensing_enabled,
:offline_cloud_licensing_enabled, :auto_renew_enabled, :seat_reconciliation_enabled,
:operational_metrics_enabled, :generated_from_customers_dot
:operational_metrics_enabled, :generated_from_customers_dot,
:generated_from_cancellation
alias_method :issued_at, :starts_at
alias_method :issued_at=, :starts_at=
@@ -65,43 +90,30 @@ module Gitlab
def valid?
if !licensee || !licensee.is_a?(Hash) || licensee.empty?
puts "Invalid License - licensee is not a hash or is empty"
false
elsif !starts_at || !starts_at.is_a?(Date)
puts "Invalid License - starts_at is not a date"
false
elsif !expires_at && !gl_team_license? && !jh_team_license?
puts "Invalid License - expires_at is not a date"
false
elsif expires_at && !expires_at.is_a?(Date)
puts "Invalid License - expires_at is not a date"
false
elsif notify_admins_at && !notify_admins_at.is_a?(Date)
puts "Invalid License - notify_admins_at is not a date"
false
elsif notify_users_at && !notify_users_at.is_a?(Date)
puts "Invalid License - notify_users_at is not a date"
false
elsif block_changes_at && !block_changes_at.is_a?(Date)
puts "Invalid License - block_changes_at is not a date"
false
elsif last_synced_at && !last_synced_at.is_a?(DateTime)
puts "Invalid License - last_synced_at is not a datetime"
false
elsif next_sync_at && !next_sync_at.is_a?(DateTime)
puts "Invalid License - next_sync_at is not a datetime"
false
elsif activated_at && !activated_at.is_a?(DateTime)
puts "Invalid License - activated_at is not a datetime"
false
elsif restrictions && !restrictions.is_a?(Hash)
puts "Invalid License - restrictions is not a hash"
false
elsif !cloud_licensing? && offline_cloud_licensing?
puts "Invalid License - offline_cloud_licensing_enabled is true but cloud_licensing_enabled is false"
false
else
puts "License is valid"
true
end
end
@@ -174,6 +186,10 @@ module Gitlab
generated_from_customers_dot == true
end
def generated_from_cancellation?
generated_from_cancellation == true
end
def gl_team_license?
licensee['Company'].to_s.match?(/GitLab/i) && licensee['Email'].to_s.end_with?('@gitlab.com')
end
@@ -216,6 +232,7 @@ module Gitlab
hash['operational_metrics_enabled'] = operational_metrics?
hash['generated_from_customers_dot'] = generated_from_customers_dot?
hash['generated_from_cancellation'] = generated_from_cancellation?
hash['restrictions'] = restrictions if restricted?
@@ -265,6 +282,7 @@ module Gitlab
seat_reconciliation_enabled
operational_metrics_enabled
generated_from_customers_dot
generated_from_cancellation
].each do |attr_name|
public_send("#{attr_name}=", attributes[attr_name] == true)
end

View File

@@ -1,5 +1,5 @@
module Gitlab
class License
VERSION = '2.2.1'.freeze
VERSION = '2.4.0'.freeze
end
end

View File

@@ -1,27 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAreEfP/ncA1A5cuxBz7rS0Z9DDxdSymLwt2OUSM5WJa+dVB3z
SpQjinifdNZq+iHVt8toZBZZ02H3unbn8td0rIifoj4oVpLhvnOAVjUn5tZeUX17
tWMA+yyBpf6w6IFxeYBXFd14WOKEarS05U9B59DjBxNqSm+GzhljHO7vvTKy2xXQ
Q7Fa702DZ7jwr4DJnL87bDXfarnYksuawqtKwQbFHAOvxFj8ghBh1Gshap1abExD
4l7QWxFMTCVOkLJmXiqfOi5KuMiaMsSUsCBNQDE3A5aKvpwLGozsvpGRMy5Tt4Sg
HC7ZbgerBNe75olOoPDxZf7bBt0+O5A/UjK/HwIDAQABAoIBACb3f4hX112KugUu
OyVxidNebKnSIUSn3ahLkayrSRUTASAbwi0he8GJfLqzXrAFqx6QYCml9KVxnBHW
me6LKGOODrBOW73jFuIWgllPeky6F9MNWw7wTAT+GWP46u6AK8z93QZSZqkMwn4j
VzLYiz2HS4mHaVebHMvNVq/iQCnW9ztZnsv9HSoFt2WY2Cm/9UpAtbqrWRQTVnCt
F7E1M9KICUKyM13qOQe+d0sZWx6D8eKrFlPs4KDXATs2SuDsaWpmWj9G8alSeHEW
Ut+2MsS5BYNIVaG0KqDFRKDyTkhXzevz98r5KylFqfAB2bCnaqIE0hdOXfYd+CR0
wwRAQmECgYEA1CnEO0K+nU8tZUwdTkL3wvo6z2jEnA97Laay9D/fnAjd3q8niTyJ
2DZQJp9omTa51/7EJw6YWhYdk078ZckwebWQPtXsA7MCTXSXL3+sGmL2GohDUovH
G6zdn9sKws+U6tIOoEOMCLivEtmNM7HJXP3PViQr+rOUQV3ig/8v+s8CgYEA0c5c
Or0Ta4apaM8aD6rP2Eilb3VC8AOvSzY36gN38ki/SwVH1ZTw/hbOYlQTsnk+OkXX
205k9tc78+9GrcYSuupjqzEdZVRQSGSbT9qXMMYfM3wK2Z7i37Cehn4Qw4BOOlgR
TvsvBd0FSnzVi2wAkhx0zL1hNUXHHAYnVdOxyrECgYEAwKbkb0NePw4ElLUW71fU
DxKVkHz7+xH7sipq2WueqttKTMkTx4RXTyOSiF+75VRSURYgG68fHL50QK06d1rH
T91UjBpIY9uKvbafChyOtK8j9lfBehU+yZyg6mVGUjuYZ9oyOcjcQZciMqWlmEla
Jby7JudVoCKs/uY3p9BzSvUCgYAF7Pkn44033T7NqgPHa4ChUDPz+PDiDIiX7Dka
D+0EV8+nU8fanXFNC+HaXxuLT+dVCAH3vLgXTK7xzdFGOTDwPIyCGkoFQaNe2BCW
6cqZYw8giiFYUieAP+HKVKcujmInPbOHcoq6dKqglvQFExDVD56w5axoL8dW4Eme
H/OGkQKBgHgQeK29Ntz7LcKlXYhQPkmYn+DWAmEq4J6XjjXyCV82HgEMmhIiAKKI
UURKt4j6c7KSiAhnyITz9JeVRoAFVB3y/tSSc5E+CH3jG/G0YlToW20Itf6o8hwD
XERkPPwsXVoZWR2FcUzcO7Bspm/JvkuaL+4u1fi+eNl7uF7RRaD1
-----END RSA PRIVATE KEY-----

View File

@@ -1,9 +0,0 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAreEfP/ncA1A5cuxBz7rS
0Z9DDxdSymLwt2OUSM5WJa+dVB3zSpQjinifdNZq+iHVt8toZBZZ02H3unbn8td0
rIifoj4oVpLhvnOAVjUn5tZeUX17tWMA+yyBpf6w6IFxeYBXFd14WOKEarS05U9B
59DjBxNqSm+GzhljHO7vvTKy2xXQQ7Fa702DZ7jwr4DJnL87bDXfarnYksuawqtK
wQbFHAOvxFj8ghBh1Gshap1abExD4l7QWxFMTCVOkLJmXiqfOi5KuMiaMsSUsCBN
QDE3A5aKvpwLGozsvpGRMy5Tt4SgHC7ZbgerBNe75olOoPDxZf7bBt0+O5A/UjK/
HwIDAQAB
-----END PUBLIC KEY-----

83
make.sh
View File

@@ -1,4 +1,81 @@
#!/bin/bash
#!/bin/zsh
cd "$(dirname "$0")" || exit 1
ruby ./generate_licenses.rb
set -e
cd "$(dirname "$0")"
if [ ! -f ".root" ]; then
echo "[!] failed to locate project directory, aborting..."
exit 1
fi
WORKING_DIR=$(pwd)
mkdir temp || true
echo "[*] fetching ruby gem version..."
RB_GEM_NAME="gitlab-license"
RB_GEM_LIST_OUTPUT=$(gem list --remote $RB_GEM_NAME)
RB_GEM_VERSION=""
while IFS= read -r line; do
if [[ $line == "gitlab-license ("* ]]; then
RB_GEM_VERSION=${line#"gitlab-license ("}
RB_GEM_VERSION=${RB_GEM_VERSION%")"}
break
fi
done <<< "$RB_GEM_LIST_OUTPUT"
echo "[*] gitlab-license version: $RB_GEM_VERSION"
RB_GEM_DOWNLOAD_URL="https://rubygems.org/downloads/gitlab-license-$RB_GEM_VERSION.gem"
RB_GEM_DOWNLOAD_PATH=$(pwd)/temp/gem/gitlab-license.gem
mkdir -p $(dirname $RB_GEM_DOWNLOAD_PATH)
curl -L $RB_GEM_DOWNLOAD_URL -o $RB_GEM_DOWNLOAD_PATH
pushd $(dirname $RB_GEM_DOWNLOAD_PATH) > /dev/null
tar -xzf gitlab-license.gem
tar -xzf data.tar.gz
if [ ! -f "./lib/gitlab/license.rb" ]; then
echo "[!] failed to locate gem file, aborting..."
exit 1
fi
echo "[*] copying gem..."
rm -rf "$WORKING_DIR/lib" || true
mkdir -p "$WORKING_DIR/lib"
cp -r ./lib/gitlab/* $WORKING_DIR/lib
popd > /dev/null
pushd lib > /dev/null
echo "[*] patching lib requirements gem..."
# replace `require 'gitlab/license/` with `require 'license/` to make it work
find . -type f -exec sed -i '' 's/require '\''gitlab\/license\//require_relative '\''license\//g' {} \;
popd > /dev/null
echo "[*] updated gem"
echo "[*] fetching gitlab source code..."
GITLAB_SOURCE_CODE_DIR=$(pwd)/temp/src/
if [ -d "$GITLAB_SOURCE_CODE_DIR" ]; then
echo "[*] gitlab source code already exists, skipping cloning..."
else
echo "[*] cloning gitlab source code..."
git clone https://gitlab.com/gitlab-org/gitlab.git $GITLAB_SOURCE_CODE_DIR
fi
echo "[*] updating gitlab source code..."
pushd $GITLAB_SOURCE_CODE_DIR > /dev/null
git clean -fdx -f
git reset --hard
git pull
popd > /dev/null
echo "[*] scanning features..."
FEATURE_LIST_FILE=$(pwd)/temp/features.txt
rm -f $FEATURE_LIST_FILE || true
./feature.scan.py $GITLAB_SOURCE_CODE_DIR $FEATURE_LIST_FILE
echo "[*] generating license..."
OUTPUT_DIR=$(pwd)/output
mkdir -p $OUTPUT_DIR
ruby ./generate_licenses.rb $OUTPUT_DIR $FEATURE_LIST_FILE
echo "[*] done $(basename $0)"

View File

@@ -1,24 +0,0 @@
eyJkYXRhIjoiOW5mNE9BaTBjYmxMendXbks4TGdDOWpDeVpNM1QzYzBNdzNs
WS94WGlVR1o3UG9kNDNtWGlmSzJYcDNIXG5pWlc2UEhtVld0VFVUY3RabjF2
Rk9wWXliZm1XUjM5dkxSQVhkVzJmcFBCQjd2eWwvY3kzaWF5dEdCZkxcblIx
NWk4bmcvRlBpZ1Q2bXI1aFhoT1VKZm9xSHJ5RkE3NXV1b01IQkI0WHI4RGhl
WVpsTEt6RmJueEZJdlxuRVkxZDk0Umd4d0dxcitqSDg0ZWMwKzhWcDFYaFEy
NmhJWnpWMXRXWjY1Q2VVYVJ5TzJ2c2loeGhuRWRzXG5iOTVYWTZVaVJ6TlZs
Ty8xaHByY3A1eklBVzBJQ0lwM2c3anR2SEtCWExuUkxnUDJucTN0UkhWNXM5
T2dcbllmVkhseUZqZjRvclFpeGc1TEFVZmcwR0R6N0pDck9oc0xtWUZxTXQw
SkZkamQ5YlhGU21OdzhkN2x4M1xuWU12MitXbS9zZ1ZiQzVFa1VJWExSaHlH
bThjRjZNbEoya3N3MCttREVlNDFCem1ncHVWWWpyT01DQlJFXG56My9DSWRV
dnFqY0ljTFFYYUdFajRTNmJtdjVxTXhYQTZiR3Bkd2orTVM4Y0doYjhGVENS
UWVsRVlSVGVcbnZ1Z3lJdnZ6V2dYQWtCZk5NTU9Rd2JmMHFmOVJNK3FyN2lQ
VXkxRWlYU2hDaHloTDhnV3BNc1FvVVNUNVxuSHZDcEE1Y2dPUmV1dC9YS1RH
OHRIMFRJR2RmNjRDd3pFeENQKzN4QWJmM3IrSDJrZlhzaTFJWVhya25CXG5u
aFhGTm83Q1doNUFJVWd1SmdnPVxuIiwia2V5IjoiT3huRG1YTEozcXVOZita
K2lvU3RQMm5wa2U2K2ZMNVBpdEtJSkNkTUhNeTlHTmdhTVNoNnZlbERaUExz
XG5JK3dJaHlEZ09vc2k0OEM4Tmp6Q29oL05mV3gybDJGRmxRSkFQLytRdGd4
eDJiRnpFRlF5bk0zc0dnRUtcbkZRUkQzUGNTWkpzZGtXdkltWGEzWnlsMEg2
WEtGelgrTnE0cGhqWktuQ1dneXk3dGU4YWI5Qm5ZNVBlYVxuWUNPL1I0SGpI
MkhKTnhmamd2TWh0YThMNXgrbmt2RXhBODFIRDFsQlVXZzJlQi92RzZjblg0
YkRPRWF3XG5tVHJpMS9VLzRVcVVoQnRSYklVSnZZeGFCMC9hT3owaStLVkdw
SENSTCs3OXQveHA1NVg2bkRQWlhwdGdcbkE0WXJrbFVHUlF0RnZyMjRRMGxa
TndrS2Z4eU1pOWkrclgrVzVIa1MvQT09XG4iLCJpdiI6Im1FL1RodjE4MWJQ
eGNFaWVwdEhCWnc9PVxuIn0=