diff options
-rw-r--r-- | acl.go | 9 | ||||
-rw-r--r-- | schema.sql | 3 | ||||
-rw-r--r-- | ssh_handle_receive_pack.go | 11 | ||||
-rw-r--r-- | ssh_utils.go | 12 | ||||
-rw-r--r-- | users.go | 26 |
5 files changed, 46 insertions, 15 deletions
@@ -6,7 +6,7 @@ import ( // get_path_perm_by_group_repo_key returns the filesystem path and direct // access permission for a given repo and a provided ssh public key. -func get_path_perm_by_group_repo_key(ctx context.Context, group_name, repo_name, ssh_pubkey string) (filesystem_path string, access bool, contrib_requirements string, is_registered_user bool, err error) { +func get_path_perm_by_group_repo_key(ctx context.Context, group_name, repo_name, ssh_pubkey string) (filesystem_path string, access bool, contrib_requirements string, user_type string, err error) { err = database.QueryRow(ctx, `SELECT r.filesystem_path, @@ -15,10 +15,7 @@ func get_path_perm_by_group_repo_key(ctx context.Context, group_name, repo_name, ELSE FALSE END AS has_role_in_group, r.contrib_requirements, - CASE - WHEN u.id IS NOT NULL THEN TRUE - ELSE FALSE - END + COALESCE(u.type, '') FROM groups g JOIN @@ -33,6 +30,6 @@ func get_path_perm_by_group_repo_key(ctx context.Context, group_name, repo_name, g.name = $1 AND r.name = $2;`, group_name, repo_name, ssh_pubkey, - ).Scan(&filesystem_path, &access, &contrib_requirements, &is_registered_user) + ).Scan(&filesystem_path, &access, &contrib_requirements, &user_type) return } @@ -48,7 +48,8 @@ CREATE TABLE mailing_list_emails ( CREATE TABLE users ( id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY, - username TEXT NOT NULL UNIQUE, + username TEXT UNIQUE, + type TEXT NOT NULL CHECK (type IN ('pubkey_only', 'registered')), password TEXT ); diff --git a/ssh_handle_receive_pack.go b/ssh_handle_receive_pack.go index ba83397..293bb36 100644 --- a/ssh_handle_receive_pack.go +++ b/ssh_handle_receive_pack.go @@ -21,7 +21,7 @@ var pack_to_hook_by_cookie = cmap.Map[string, pack_to_hook_t]{} // ssh_handle_receive_pack handles attempts to push to repos. func ssh_handle_receive_pack(session glider_ssh.Session, pubkey string, repo_identifier string) (err error) { - repo_path, direct_access, contrib_requirements, is_registered_user, err := get_repo_path_perms_from_ssh_path_pubkey(session.Context(), repo_identifier, pubkey) + repo_path, direct_access, contrib_requirements, user_type, err := get_repo_path_perms_from_ssh_path_pubkey(session.Context(), repo_identifier, pubkey) if err != nil { return err } @@ -33,13 +33,20 @@ func ssh_handle_receive_pack(session glider_ssh.Session, pubkey string, repo_ide return errors.New("You need direct access to push to this repo.") } case "registered_user": - if !is_registered_user { + if user_type != "registered" { return errors.New("You need to be a registered user to push to this repo.") } case "ssh_pubkey": if pubkey == "" { return errors.New("You need to have an SSH public key to push to this repo.") } + if user_type == "" { + user_id, err := add_user_ssh(session.Context(), pubkey) + if err != nil { + return err + } + fmt.Fprintln(session.Stderr(), "You are now registered as user ID", user_id) + } case "public": default: panic("unknown contrib_requirements value " + contrib_requirements) diff --git a/ssh_utils.go b/ssh_utils.go index bf8bf5e..fb8f920 100644 --- a/ssh_utils.go +++ b/ssh_utils.go @@ -9,19 +9,19 @@ import ( var err_ssh_illegal_endpoint = errors.New("illegal endpoint during SSH access") -func get_repo_path_perms_from_ssh_path_pubkey(ctx context.Context, ssh_path string, ssh_pubkey string) (repo_path string, direct_access bool, contrib_requirements string, is_registered_user bool, err error) { +func get_repo_path_perms_from_ssh_path_pubkey(ctx context.Context, ssh_path string, ssh_pubkey string) (repo_path string, direct_access bool, contrib_requirements string, user_type string, err error) { segments := strings.Split(strings.TrimPrefix(ssh_path, "/"), "/") for i, segment := range segments { var err error segments[i], err = url.PathUnescape(segment) if err != nil { - return "", false, "", false, err + return "", false, "", "", err } } if segments[0] == ":" { - return "", false, "", false, err_ssh_illegal_endpoint + return "", false, "", "", err_ssh_illegal_endpoint } separator_index := -1 @@ -37,9 +37,9 @@ func get_repo_path_perms_from_ssh_path_pubkey(ctx context.Context, ssh_path stri switch { case separator_index == -1: - return "", false, "", false, err_ssh_illegal_endpoint + return "", false, "", "", err_ssh_illegal_endpoint case len(segments) <= separator_index+2: - return "", false, "", false, err_ssh_illegal_endpoint + return "", false, "", "", err_ssh_illegal_endpoint } group_name := segments[0] @@ -49,6 +49,6 @@ func get_repo_path_perms_from_ssh_path_pubkey(ctx context.Context, ssh_path stri case "repos": return get_path_perm_by_group_repo_key(ctx, group_name, module_name, ssh_pubkey) default: - return "", false, "", false, err_ssh_illegal_endpoint + return "", false, "", "", err_ssh_illegal_endpoint } } diff --git a/users.go b/users.go new file mode 100644 index 0000000..9ac0798 --- /dev/null +++ b/users.go @@ -0,0 +1,26 @@ +package main + +import ( + "context" +) + +func add_user_ssh(ctx context.Context, pubkey string) (user_id int, err error) { + tx, err := database.Begin(ctx) + if err != nil { + return + } + defer tx.Rollback(ctx) + + err = tx.QueryRow(ctx, `INSERT INTO users (type) VALUES ('pubkey_only') RETURNING id`).Scan(&user_id) + if err != nil { + return + } + + _, err = tx.Exec(ctx, `INSERT INTO ssh_public_keys (key_string, user_id) VALUES ($1, $2)`, pubkey, user_id) + if err != nil { + return + } + + err = tx.Commit(ctx) + return +} |