summaryrefslogtreecommitdiff
path: root/src/init
blob: fd5bb12709350f94fe0660b3cd76fac37c5a6050 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#!/usr/bin/env fish

# load common environment
source (status dirname)/env

###
###
### functions
###
###

function fail
    set_color red
    echo "$argv"
    set_color normal
    return 1
end

function checkUser
	set -l user $argv[1]
	grep -q -E "^$user:" < /etc/passwd
	return $status
end

function setupUser
	set -l userConfig (string split ':' $argv[1])
	set -l user $userConfig[1]
	set -l key $userConfig[2]
	set -l HOME "/home/$user"

	echo "Setting up user: $user"
	if [ "$user" = git ]
		echo "Error: User git is reserved"
		return 1
	end
	
	# setup user exist if necessary
	if not checkUser "$user"
		# user is not restricted, this is done in ssh config with forceCommand
		# we need to be able to run a fish script to check for permissions
		adduser --home $HOME -D "$user"; or fail "Failed to create user $user"
		# add user to sudo group
		addgroup "$user" $_GIT_SUDO_GROUP; or fail "Failed to add user $user to group $_GIT_SUDO_GROUP"
		# unlock account to allow ssh logins
		passwd -u "$user" &>/dev/null; or fail "Failed to unlock account of $user"
		# create ssh folder
		mkdir "$HOME/.ssh"
	end	

	# Copy/Overwrite ssh key
	echo "$key" > "$HOME/.ssh/authorized_keys"
	chown -R $user "$HOME"
	chmod -R 700 "$HOME"
end

function setupGitUser
	checkUser "git"; and return 0
	echo "Setting up git user"
	# git user has read/write access to all repos, set git-shell
	# and no password login allowed -> no ssh login possible
	addgroup -g $GIT_GID git; or fail "Failed to create git user group"
	adduser git -u $GIT_UID -G git -D --shell "/usr/bin/git-shell"; or fail "Failed to setup git user"
	# group that is allowed to sudo
	addgroup $_GIT_SUDO_GROUP; or fail "Failed to setup git sudo group"
end

function setupRepo
	set -l repoConfig $argv[1]
	set -l parsedConfig (string split ';' -- $repoConfig)
	set -l repo $parsedConfig[1]

	# check repo name
	set -l matcher (string match -r -g "^$_REPO_VALIDATION_REGEX\$" -- $repo)
	if test -z $matcher[1]
		fail "Failed to setup repo, invalid config: $repoConfig"
		return 1
	end

	# we assume all repos to be in /srv/repos
	set -l repoDir srv repos
	set repoDir /(string join -n '/' $repoDir (string split '/' $repo))
	echo "Setting up repo: $repo"

	# write user as allowed into permission file
	for userConfig in $parsedConfig[2..]
		set -l parsedConfig (string split ':' -- $userConfig)
		set -l user $parsedConfig[1]
		set -l permission $parsedConfig[2]
		
		# check for valid permission
		if not contains $permission $_PERMISSIONS
			set permission "r"
		end
		echo "$repoDir:$user:$permission" >> $_REPO_PERMISSIONS_FILE
	end

	# setup repo dir
	if not test -d $repoDir
		mkdir -p $repoDir
		git init --bare $repoDir -b trunk
	end
	chown -R git:git "$repoDir"
	chmod -R 700 "$repoDir"
end

function setupSSH
	echo "Setting up server"
	
	# generate host keys in case
	mkdir -p /var/ssh/etc/ssh/ && ssh-keygen -A -f /var/ssh
end

function setupRepoPermissionACL
	echo -n > $_REPO_PERMISSIONS_FILE
	chown root:$_GIT_SUDO_GROUP $_REPO_PERMISSIONS_FILE
	chmod 740 $_REPO_PERMISSIONS_FILE
end

###
###
### main
###
###

argparse 'g/git-uid=?' 'u/user=+' 'r/repo=+' 'h/help' 'v/version' -- $argv
or exit 1;

if set -q _flag_h
	echo "Usage: $(status filename) [ OPTIONS ]..."
	echo -e ""
	echo -e "OPTIONS"
	echo -e "\t -h, --help \t\t Display this page"
	echo -e "\t -g, --git-uid \t\t UID of the git user that is used also as ownership for all repos"
	echo -e "\t -u, --user \t\t User setting in form of <user-name>:<public-key>"
	echo -e "\t -r, --repo \t\t Repo setting in form of <repo-path>;<user>:<perm>[;<user2>:<perm>;...]. You can add as many users as you want. If you do not specify a user for a repo, that user does not have access to it. If you specify a user without permission, the default fallback is read only."
	echo -e "\t -v, --version \t\t Version"
	echo -e ""
	return
end

if set -q _flag_v
	echo -e "$_VERSION"
	return
end

function showBanner
	echo
	echo $_BANNER
	echo
	echo Copyright Matthias Jaros 2026
	echo This software is licensed under GPLv3. See /usr/share/doc/gitreef/LICENSE
	echo
end

showBanner

# read variables
set -l users $_flag_u
for user in (set -n | string match -r "^USER_\S+")
	set users $users $$user
end

set -l repos $_flag_r
for repo in (set -n | string match -r "^REPO_\S+")
	set repos $repos $$repo
end

if set -q $_flag_g
	set GIT_UID $_flag_g
end

# Setup git user
setupGitUser; or return $status
# Setup users
for userConfig in $users
	setupUser "$userConfig"
end

# Setup repos
setupRepoPermissionACL
for repoConfig in $repos
	setupRepo "$repoConfig"
end

# create writable log file for run script
touch $_LOG && chmod 777 $_LOG

setupSSH; or return $status

# run ssh daemon
exec /usr/sbin/sshd -D -e