File: username.go

package info (click to toggle)
golang-github-juju-utils 0.0~git20171220.f38c0b0-5
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 1,748 kB
  • sloc: makefile: 20
file content (77 lines) | stat: -rw-r--r-- 2,323 bytes parent folder | download | duplicates (3)
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
// Copyright 2015 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.

package utils

import (
	"os"
	"os/user"

	"github.com/juju/errors"
)

// ResolveSudo returns the original username if sudo was used. The
// original username is extracted from the OS environment.
func ResolveSudo(username string) string {
	return resolveSudo(username, os.Getenv)
}

func resolveSudo(username string, getenvFunc func(string) string) string {
	if username != "root" {
		return username
	}
	// sudo was probably called, get the original user.
	if username := getenvFunc("SUDO_USER"); username != "" {
		return username
	}
	return username
}

// EnvUsername returns the username from the OS environment.
func EnvUsername() (string, error) {
	return os.Getenv("USER"), nil
}

// OSUsername returns the username of the current OS user (based on UID).
func OSUsername() (string, error) {
	u, err := user.Current()
	if err != nil {
		return "", errors.Trace(err)
	}
	return u.Username, nil
}

// ResolveUsername returns the username determined by the provided
// functions. The functions are tried in the same order in which they
// were passed in. An error returned from any of them is immediately
// returned. If an empty string is returned then that signals that the
// function did not find the username and the next function is tried.
// Once a username is found, the provided resolveSudo func (if any) is
// called with that username and the result is returned. If no username
// is found then errors.NotFound is returned.
func ResolveUsername(resolveSudo func(string) string, usernameFuncs ...func() (string, error)) (string, error) {
	for _, usernameFunc := range usernameFuncs {
		username, err := usernameFunc()
		if err != nil {
			return "", errors.Trace(err)
		}
		if username != "" {
			if resolveSudo != nil {
				if original := resolveSudo(username); original != "" {
					username = original
				}
			}
			return username, nil
		}
	}
	return "", errors.NotFoundf("username")
}

// LocalUsername determines the current username on the local host.
func LocalUsername() (string, error) {
	username, err := ResolveUsername(ResolveSudo, EnvUsername, OSUsername)
	if err != nil {
		return "", errors.Annotatef(err, "cannot get current user from the environment: %v", os.Environ())
	}
	return username, nil
}