GitRoot
craft your forge, build your project, grow your community freely
1// SPDX-FileCopyrightText: 2025 Romain Maneschi <romain@gitroot.dev>
2//
3// SPDX-License-Identifier: EUPL-1.2
4
5package repository
6
7import (
8 "errors"
9 "fmt"
10
11 "github.com/go-git/go-git/v5/plumbing"
12 "github.com/samber/oops"
13 "gitroot.dev/server/user"
14)
15
16func (repo *GitRootRepository) CanWrite(userSsh string, branch string) (bool, *user.GitRootUser, error) {
17 users, err := repo.ContentAtRef(repo.manager.conf.PathFileUsers(), plumbing.NewBranchReferenceName(branch))
18 if errors.Is(err, plumbing.ErrReferenceNotFound) {
19 users, err = repo.contentUsersConf()
20 }
21 if err != nil {
22 return false, nil, repo.errorHandler.Wrapf(err, "Reference")
23 }
24 currentUser, err := user.FindUser(users, branch, userSsh)
25 if err != nil {
26 return false, nil, repo.errorHandler.With("ssh", userSsh).Wrapf(err, "FindUser")
27 }
28 return currentUser.CanWrite(branch), currentUser, nil
29}
30
31func (repo *GitRootRepositoryWrite) AddUserInfo(u *user.GitRootUser, branch string) (plumbing.Hash, error) {
32 currentBranch, err := repo.repo.CurrentBranch()
33 if err != nil {
34 return plumbing.ZeroHash, oops.Wrapf(err, "can't get currentBranch")
35 }
36 if err := repo.Checkout(plumbing.NewBranchReferenceName(branch)); err != nil {
37 return plumbing.ZeroHash, oops.With("branch", branch).Wrapf(err, "can't checkout")
38 }
39 fileUsersContent, err := repo.repo.contentUsersConf()
40 if err != nil {
41 return plumbing.ZeroHash, oops.Wrapf(err, "can't readAll file users")
42 }
43 newFileUsersContent, err := user.AppendBranch(fileUsersContent, branch, user.SimpleUser{Pseudo: u.Pseudo, Email: u.Email, Ssh: u.PubKey})
44 if err != nil {
45 return plumbing.ZeroHash, oops.Wrapf(err, "can't AppendUser")
46 }
47
48 if err := repo.Write(repo.repo.manager.conf.PathFileUsers(), newFileUsersContent); err != nil {
49 return plumbing.ZeroHash, oops.Wrapf(err, "Write")
50 }
51
52 hash, err := repo.CommitAll(fmt.Sprintf("Add user for branch %s", branch), repo.repo.manager.userManager.RootCommiter())
53 if err != nil {
54 return plumbing.ZeroHash, oops.Wrapf(err, "CommitAll")
55 }
56 return hash, repo.Checkout(currentBranch)
57}
58
59func (repo *GitRootRepositoryWrite) DeleteBranchInFilesAndCommit(branch string) (plumbing.Hash, error) {
60 fileUsersContent, err := repo.repo.contentUsersConf()
61 if err != nil {
62 return plumbing.ZeroHash, oops.Wrapf(err, "can't readAll file users")
63 }
64 newFileUsersContent, err := user.DeleteGroupAndBranch(fileUsersContent, branch)
65 if err != nil {
66 return plumbing.ZeroHash, oops.Wrapf(err, "can't DeleteGroupAndBranch")
67 }
68
69 if err := repo.Write(repo.repo.manager.conf.PathFileUsers(), newFileUsersContent); err != nil {
70 return plumbing.ZeroHash, oops.Wrapf(err, "Write")
71 }
72
73 if h, err := repo.CommitAll(fmt.Sprintf("Delete branch %s", branch), repo.repo.manager.userManager.RootCommiter()); err != nil {
74 return plumbing.ZeroHash, oops.Wrapf(err, "CommitAll")
75 } else {
76 return h, nil
77 }
78}
79
80func (repo *GitRootRepository) AppendUserToGroup(groupName string, users ...user.SimpleUser) ([]byte, error) {
81 fileUsersContent, err := repo.contentUsersConf()
82 if err != nil {
83 return nil, oops.Wrapf(err, "can't read users file")
84 }
85 return user.AppendUserToGroup(fileUsersContent, groupName, users...)
86}
87
88func (repo *GitRootRepository) contentUsersConf() ([]byte, error) {
89 return repo.Content(repo.manager.conf.PathFileUsers())
90}