Skip to content

Commit

Permalink
Merge pull request #130 from jmpsec/default-env-user
Browse files Browse the repository at this point in the history
Default environment per user can be selected on user creation
  • Loading branch information
javuto authored Jan 10, 2021
2 parents 175f09f + a6e1281 commit 9ce4d74
Show file tree
Hide file tree
Showing 17 changed files with 265 additions and 37 deletions.
2 changes: 1 addition & 1 deletion admin/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ func handlerAuthCheck(h http.Handler) http.Handler {
http.Redirect(w, r, forbiddenPath, http.StatusForbidden)
return
}
newUser, err := adminUsers.New(username, "", email, fullname, (s[ctxLevel] == adminLevel))
newUser, err := adminUsers.New(username, "", email, fullname, headersConfig.DefaultEnv, (s[ctxLevel] == adminLevel))
if err != nil {
log.Printf("Error with new user %s: %v", username, err)
http.Redirect(w, r, forbiddenPath, http.StatusFound)
Expand Down
42 changes: 30 additions & 12 deletions admin/handlers/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ func (h *HandlersAdmin) LoginPOSTHandler(w http.ResponseWriter, r *http.Request)
}
permissions, err := h.Users.ConvertPermissions(user.Permissions.RawMessage)
if err != nil {

adminErrorResponse(w, "error processing login", http.StatusInternalServerError, err)
h.Inc(metricAdminErr)
return
}
_, err = h.Sessions.Save(r, w, user, permissions)
if err != nil {
Expand All @@ -52,7 +54,7 @@ func (h *HandlersAdmin) LoginPOSTHandler(w http.ResponseWriter, r *http.Request)
if h.Settings.DebugService(settings.ServiceAdmin) {
log.Println("DebugService: Login response sent")
}
adminOKResponse(w, "OK")
adminOKResponse(w, "/environment/"+user.DefaultEnv+"/active")
h.Inc(metricAdminOK)
}

Expand Down Expand Up @@ -987,7 +989,7 @@ func (h *HandlersAdmin) EnvsPOSTHandler(w http.ResponseWriter, r *http.Request)
adminOKResponse(w, "environment created successfully")
case "delete":
if c.Name == h.Settings.DefaultEnv(settings.ServiceAdmin) {
adminErrorResponse(w, "not a good idea", http.StatusInternalServerError, fmt.Errorf("attempt to remove environment %s", c.Name))
adminErrorResponse(w, "nope, this is the default environment", http.StatusInternalServerError, fmt.Errorf("attempt to remove default environment %s", c.Name))
h.Inc(metricAdminErr)
return
}
Expand Down Expand Up @@ -1153,8 +1155,14 @@ func (h *HandlersAdmin) UsersPOSTHandler(w http.ResponseWriter, r *http.Request)
h.Inc(metricAdminErr)
return
}
// Check that default environment exists
if (u.DefaultEnv == "") || !h.Envs.Exists(u.DefaultEnv) {
adminErrorResponse(w, "error adding user", http.StatusInternalServerError, fmt.Errorf("environment %s does not exist", u.DefaultEnv))
h.Inc(metricAdminErr)
return
}
// Prepare user to create
newUser, err := h.Users.New(u.Username, u.Password, u.Email, u.Fullname, u.Admin)
newUser, err := h.Users.New(u.Username, u.Password, u.Email, u.Fullname, u.DefaultEnv, u.Admin)
if err != nil {
adminErrorResponse(w, "error with new user", http.StatusInternalServerError, err)
h.Inc(metricAdminErr)
Expand All @@ -1166,19 +1174,22 @@ func (h *HandlersAdmin) UsersPOSTHandler(w http.ResponseWriter, r *http.Request)
h.Inc(metricAdminErr)
return
}
namesEnvs := []string{u.DefaultEnv}
access := users.EnvLevel
if u.Admin {
namesEnvs, err := h.Envs.Names()
access = users.AdminLevel
namesEnvs, err = h.Envs.Names()
if err != nil {
adminErrorResponse(w, "error getting environments user", http.StatusInternalServerError, err)
h.Inc(metricAdminErr)
return
}
perms := h.Users.GenPermissions(namesEnvs, u.Admin)
if err := h.Users.ChangePermissions(u.Username, perms); err != nil {
adminErrorResponse(w, "error changing permissions", http.StatusInternalServerError, err)
h.Inc(metricAdminErr)
return
}
}
perms := h.Users.GenPermissions(namesEnvs, access)
if err := h.Users.ChangePermissions(u.Username, perms); err != nil {
adminErrorResponse(w, "error changing permissions", http.StatusInternalServerError, err)
h.Inc(metricAdminErr)
return
}
if u.Token {
token, exp, err := h.Users.CreateToken(newUser.Username)
Expand Down Expand Up @@ -1209,6 +1220,13 @@ func (h *HandlersAdmin) UsersPOSTHandler(w http.ResponseWriter, r *http.Request)
return
}
}
if u.DefaultEnv != "" {
if err := h.Users.ChangeDefaultEnv(u.Username, u.DefaultEnv); err != nil {
adminErrorResponse(w, "error changing default environment", http.StatusInternalServerError, err)
h.Inc(metricAdminErr)
return
}
}
adminOKResponse(w, "user updated successfully")
case "remove":
if u.Username == ctx[sessions.CtxUser] {
Expand Down Expand Up @@ -1243,7 +1261,7 @@ func (h *HandlersAdmin) UsersPOSTHandler(w http.ResponseWriter, r *http.Request)
h.Inc(metricAdminErr)
return
}
perms := h.Users.GenPermissions(namesEnvs, u.Admin)
perms := h.Users.GenPermissions(namesEnvs, users.AdminLevel)
if err := h.Users.ChangePermissions(u.Username, perms); err != nil {
adminErrorResponse(w, "error changing permissions", http.StatusInternalServerError, err)
h.Inc(metricAdminErr)
Expand Down
17 changes: 9 additions & 8 deletions admin/handlers/types-requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,15 @@ type EnvironmentsRequest struct {

// UsersRequest to receive user action requests
type UsersRequest struct {
CSRFToken string `json:"csrftoken"`
Action string `json:"action"`
Username string `json:"username"`
Email string `json:"email"`
Fullname string `json:"fullname"`
Password string `json:"password"`
Token bool `json:"token"`
Admin bool `json:"admin"`
CSRFToken string `json:"csrftoken"`
Action string `json:"action"`
Username string `json:"username"`
Email string `json:"email"`
Fullname string `json:"fullname"`
Password string `json:"password"`
Token bool `json:"token"`
Admin bool `json:"admin"`
DefaultEnv string `json:"environment"`
}

// TagsRequest to receive tag action requests
Expand Down
4 changes: 3 additions & 1 deletion admin/static/js/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ function sendLogin() {
username: _user,
password: _password
};
sendPostRequest(data, _url, '/dashboard', false);
sendPostRequest(data, _url, '', false, function(_data){
window.location.replace(_data.message);
});
}

function sendLogout() {
Expand Down
4 changes: 3 additions & 1 deletion admin/static/js/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ function confirmAddUser() {
var _password = $("#user_password").val();
var _admin = $("#user_admin").is(':checked');
var _token = $("#user_token").is(':checked');
var _env = $("#default_env").val();

var data = {
csrftoken: _csrftoken,
Expand All @@ -26,7 +27,8 @@ function confirmAddUser() {
fullname: _fullname,
password: _password,
admin: _admin,
token: _token
token: _token,
environment: _env
};
sendPostRequest(data, _url, _url, false);
}
Expand Down
26 changes: 21 additions & 5 deletions admin/templates/users.html
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ <h4 class="modal-title">Add new user</h4>
<div class="col-md-4">
<input class="form-control" name="user_password" id="user_password" type="password" autocomplete="off">
</div>

</div>
<div class="form-group row">
<label class="col-md-2 col-form-label" for="user_email">Email: </label>
Expand All @@ -138,20 +137,32 @@ <h4 class="modal-title">Add new user</h4>
</div>
</div>
<div class="form-group row">
<label class="col-md-3 col-form-label" for="user_admin">Enable Admin Level: </label>
<div class="col-md-3">
<label class="col-md-1 col-form-label" for="user_admin">Admin: </label>
<div class="col-md-2">
<label class="switch switch-label switch-pill switch-success switch-sm" data-tooltip="true" data-placement="top" title="Change">
<input id="user_admin" class="switch-input" type="checkbox">
<span class="switch-slider" data-checked="On" data-unchecked="Off"></span>
</label>
</div>
<label class="col-md-3 col-form-label" for="user_token">Create API Token: </label>
<div class="col-md-3">
<label class="col-md-1 col-form-label" for="user_token">API: </label>
<div class="col-md-2">
<label class="switch switch-label switch-pill switch-success switch-sm" data-tooltip="true" data-placement="top" title="Change">
<input id="user_token" class="switch-input" type="checkbox">
<span class="switch-slider" data-checked="On" data-unchecked="Off"></span>
</label>
</div>

<label class="col-md-3 col-form-label" for="default_env">Default Environment: </label>
<div class="col-md-3">
<select class="form-control" style="width: 100%;" name="default_env" id="default_env">
<option value=""></option>
{{ range $i, $e := $.Environments }}
<option value="{{ $e.Name }}">{{ $e.Name }}</option>
{{ end }}
</select>
<small class="text-muted">read access will be granted</small>
</div>

</div>
</div>
<div class="modal-footer">
Expand Down Expand Up @@ -335,6 +346,11 @@ <h4 class="modal-title">User Permissions</h4>
// Enable all tooltips
$('[data-tooltip="true"]').tooltip({trigger : 'hover'});

// Select2 initialization
$('#default_env').select2({
theme: "classic"
});

// Clipboard.js initialization
var clipboard_sh = new ClipboardJS('#button-clipboard-sh');
clipboard_sh.on('success', function(e) {
Expand Down
9 changes: 9 additions & 0 deletions cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ func init() {
Hidden: false,
Usage: "Make this user an admin",
},
cli.StringFlag{
Name: "environment, E",
Value: "",
Usage: "Default environment for the new user",
},
cli.StringFlag{
Name: "email, e",
Usage: "Email for the new user",
Expand Down Expand Up @@ -125,6 +130,10 @@ func init() {
Hidden: false,
Usage: "Make this user an non-admin",
},
cli.StringFlag{
Name: "environment, E",
Usage: "Default environment for this user",
},
},
Action: cliWrapper(editUser),
},
Expand Down
31 changes: 30 additions & 1 deletion cli/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"os"

"github.com/jmpsec/osctrl/users"
"github.com/olekukonko/tablewriter"
"github.com/urfave/cli"
)
Expand All @@ -20,17 +21,37 @@ func addUser(c *cli.Context) error {
fmt.Println("username is required")
os.Exit(1)
}
defaultEnv := c.String("environment")
if defaultEnv == "" {
fmt.Println("environment is required")
os.Exit(1)
}
password := c.String("password")
email := c.String("email")
fullname := c.String("fullname")
admin := c.Bool("admin")
user, err := adminUsers.New(username, password, email, fullname, admin)
user, err := adminUsers.New(username, password, email, fullname, defaultEnv, admin)
if err != nil {
return err
}
// Create user
if err := adminUsers.Create(user); err != nil {
return err
}
// Assign permissions to user
permEnv := []string{defaultEnv}
access := users.EnvLevel
if admin {
access = users.AdminLevel
permEnv, err = envs.Names()
if err != nil {
return err
}
}
perms := adminUsers.GenPermissions(permEnv, access)
if err := adminUsers.ChangePermissions(username, perms); err != nil {
return err
}
fmt.Printf("Created user %s successfully", username)
return nil
}
Expand Down Expand Up @@ -72,6 +93,12 @@ func editUser(c *cli.Context) error {
return err
}
}
defaultEnv := c.String("environment")
if defaultEnv != "" {
if err := adminUsers.ChangeDefaultEnv(username, defaultEnv); err != nil {
return err
}
}
fmt.Printf("Edited user %s successfully", username)
return nil
}
Expand All @@ -97,6 +124,7 @@ func listUsers(c *cli.Context) error {
"Fullname",
"PassHash",
"Admin?",
"Environment",
"Last IPAddress",
"Last UserAgent",
})
Expand All @@ -108,6 +136,7 @@ func listUsers(c *cli.Context) error {
u.Fullname,
truncateString(u.PassHash, lengthToTruncate),
stringifyBool(u.Admin),
u.DefaultEnv,
u.LastIPAddress,
u.LastUserAgent,
}
Expand Down
2 changes: 1 addition & 1 deletion deploy/docker/admin/wait.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ SECRET_FILE="$CONFIG/docker.secret"
./bin/osctrl-cli -D "$DB_JSON" environment flags -n dev -crt "/$CRT_FILE" -secret "/$SECRET_FILE" | sed 's/=uuid/=ephemeral/g' > "$FLAGS_FILE"

# Create admin user
OUTPUT_ADMIN="$(./bin/osctrl-cli -D "$DB_JSON" user add -u admin -p admin -a -n Admin)"
OUTPUT_ADMIN="$(./bin/osctrl-cli -D "$DB_JSON" user add -u admin -p admin -a -E dev -n Admin)"
if [ $? -eq 0 ]; then
echo "Created admin user"
else
Expand Down
2 changes: 1 addition & 1 deletion deploy/provision.sh
Original file line number Diff line number Diff line change
Expand Up @@ -724,7 +724,7 @@ else

# Create admin user
log "Creating admin user"
"$DEST_PATH"/osctrl-cli -D "$__db_conf" user add -u "$_ADMIN_USER" -p "$_ADMIN_PASS" -a -n "Admin"
"$DEST_PATH"/osctrl-cli -D "$__db_conf" user add -u "$_ADMIN_USER" -p "$_ADMIN_PASS" -a -E "$ENVIRONMENT" -n "Admin"

# Create initial environment to enroll machines
log "Creating environment $ENVIRONMENT"
Expand Down
2 changes: 2 additions & 0 deletions types/go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/jmpsec/osctrl/types

go 1.15

require github.com/jmpsec/osctrl/queries v0.0.0-20210108060250-175f09fbfa70
Loading

0 comments on commit 9ce4d74

Please sign in to comment.