From aeb852e168934cbc390b5a393db2bc7ef3605005 Mon Sep 17 00:00:00 2001 From: RachelElysia <71795832+RachelElysia@users.noreply.github.com> Date: Thu, 24 Jun 2021 13:42:29 -0700 Subject: [PATCH] Remove username from UI (#1168) * Remove username from UI code * Remove username from tests * Remove username from database * Modify server endpoints for removing username * Implement backend aspects of removing username * Update API docs * Add name to fleetctl --- Makefile | 8 +- cmd/fleetctl/login.go | 4 +- cmd/fleetctl/preview.go | 10 +- cmd/fleetctl/setup.go | 26 ++- cmd/fleetctl/user.go | 14 +- .../integration/all/app/activateuser.spec.ts | 4 +- cypress/integration/all/setup/setup.spec.ts | 6 +- cypress/support/commands.ts | 12 +- cypress/support/index.d.ts | 11 +- docs/1-Using-Fleet/2-fleetctl-CLI.md | 4 +- docs/1-Using-Fleet/3-REST-API.md | 186 +++++++----------- docs/1-Using-Fleet/FAQ.md | 14 +- .../ConfirmInviteForm/ConfirmInviteForm.jsx | 4 +- .../ConfirmInviteForm.tests.jsx | 20 -- .../forms/ConfirmInviteForm/helpers.js | 5 - .../ConfirmSSOInviteForm.jsx | 4 +- .../ConfirmSSOInviteForm.tests.jsx | 20 -- .../forms/ConfirmSSOInviteForm/helpers.js | 6 +- .../components/forms/LoginForm/LoginForm.jsx | 10 +- .../forms/LoginForm/LoginForm.tests.jsx | 18 +- .../components/forms/LoginForm/validate.js | 6 +- .../AdminDetails/AdminDetails.jsx | 18 +- .../AdminDetails/AdminDetails.tests.jsx | 10 +- .../RegistrationForm/AdminDetails/helpers.js | 6 +- .../ConfirmationPage.tests.jsx | 10 +- .../ConfirmationPage/ConfirmationPage.tsx | 6 +- .../UserSettingsForm/UserSettingsForm.jsx | 10 +- .../UserSettingsForm.tests.jsx | 5 - .../forms/fields/InputField/_styles.scss | 2 +- .../side_panels/UserMenu/UserMenu.jsx | 2 +- frontend/fleet/entities/account.tests.js | 1 - frontend/fleet/entities/sessions.js | 4 +- frontend/fleet/entities/sessions.tests.js | 2 +- frontend/fleet/helpers.tests.js | 2 - frontend/fleet/helpers.ts | 8 +- frontend/interfaces/registration_form_data.js | 2 +- frontend/interfaces/registration_form_data.ts | 4 +- frontend/interfaces/user.ts | 2 - .../UserSettingsPage/UserSettingsPage.jsx | 2 +- .../UserManagementPage/UserManagementPage.jsx | 1 - frontend/redux/nodes/auth/actions.js | 2 +- frontend/redux/nodes/auth/reducer.tests.js | 2 +- frontend/test/stubs.ts | 2 - server/contexts/viewer/viewer.go | 6 +- server/contexts/viewer/viewer_test.go | 17 +- server/datastore/datastore_campaigns.go | 4 +- server/datastore/datastore_email_changes.go | 2 - server/datastore/datastore_packs.go | 2 +- server/datastore/datastore_queries.go | 18 +- .../datastore/datastore_scheduled_queries.go | 10 +- server/datastore/datastore_unicode.go | 6 +- server/datastore/datastore_users.go | 30 ++- server/datastore/inmem/inmem.go | 6 +- server/datastore/inmem/users.go | 17 +- .../tables/20210623100031_RemoveUsername.go | 36 ++++ server/datastore/mysql/queries.go | 2 +- server/datastore/mysql/users.go | 38 ++-- server/fleet/sessions.go | 2 +- server/fleet/users.go | 15 +- server/fleet/users_test.go | 13 +- server/mail/invite.go | 8 +- server/mail/templates/invite_token.html | 32 +++ server/mock/datastore_users.go | 10 - server/service/client_sessions.go | 2 +- server/service/client_setup.go | 4 +- server/service/endpoint_sessions.go | 4 +- server/service/endpoint_setup.go | 2 +- server/service/endpoint_test.go | 4 +- server/service/http_auth_test.go | 16 +- server/service/logging_campaigns.go | 6 +- server/service/logging_invites.go | 6 +- server/service/logging_labels.go | 8 +- server/service/logging_packs.go | 8 +- server/service/logging_queries.go | 11 +- server/service/logging_scheduled_queries.go | 7 +- server/service/logging_sessions.go | 6 +- server/service/logging_users.go | 54 ++--- server/service/metrics_sessions.go | 4 +- server/service/service_campaigns.go | 2 +- server/service/service_invites.go | 12 +- server/service/service_sessions.go | 14 +- server/service/service_sessions_test.go | 25 ++- server/service/service_users.go | 6 - server/service/service_users_test.go | 32 +-- server/service/transport_sessions.go | 2 +- server/service/transport_sessions_test.go | 10 +- server/service/util_test.go | 11 +- server/service/validation_users.go | 62 +++--- server/test/new_objects.go | 3 +- server/test/users.go | 6 +- tools/api/README.md | 3 +- tools/api/fleet/teams/create_basic | 5 - tools/api/fleet/teams/create_core | 3 - tools/api/fleet/teams/create_figma | 11 -- 94 files changed, 485 insertions(+), 633 deletions(-) create mode 100644 server/datastore/mysql/migrations/tables/20210623100031_RemoveUsername.go diff --git a/Makefile b/Makefile index 83bc744cfe..b102b1db19 100644 --- a/Makefile +++ b/Makefile @@ -213,10 +213,10 @@ e2e-reset-db: e2e-setup: ./build/fleetctl config set --context e2e --address https://localhost:8642 --tls-skip-verify true - ./build/fleetctl setup --context e2e --email=admin@example.com --username=admin --password=user123# --org-name='Fleet Test' - ./build/fleetctl user create --context e2e --email=maintainer@example.com --username=maintainer --password=user123# --global-role=maintainer - ./build/fleetctl user create --context e2e --email=observer@example.com --username=observer --password=user123# --global-role=observer - ./build/fleetctl user create --context e2e --username=sso_user --email=sso_user@example.com --sso=true + ./build/fleetctl setup --context e2e --email=admin@example.com --password=user123# --org-name='Fleet Test' --name Admin + ./build/fleetctl user create --context e2e --email=maintainer@example.com --name maintainer --password=user123# --global-role=maintainer + ./build/fleetctl user create --context e2e --email=observer@example.com --name observer --password=user123# --global-role=observer + ./build/fleetctl user create --context e2e --email=sso_user@example.com --name "SSO user" --sso=true e2e-serve-core: ./build/fleet serve --mysql_address=localhost:3307 --mysql_username=root --mysql_password=toor --mysql_database=e2e --server_address=0.0.0.0:8642 diff --git a/cmd/fleetctl/login.go b/cmd/fleetctl/login.go index 7abf69499f..9cecb24446 100644 --- a/cmd/fleetctl/login.go +++ b/cmd/fleetctl/login.go @@ -29,7 +29,7 @@ Interactively prompts for email and password if not specified in the flags or en EnvVars: []string{"EMAIL"}, Value: "", Destination: &flEmail, - Usage: "Email or username to use to log in", + Usage: "Email to use to log in", }, &cli.StringFlag{ Name: "password", @@ -52,7 +52,7 @@ Interactively prompts for email and password if not specified in the flags or en // CLI history. if flEmail == "" { fmt.Println("Log in using the standard Fleet credentials.") - fmt.Print("Email/Username: ") + fmt.Print("Email: ") _, err := fmt.Scanln(&flEmail) if err != nil { return errors.Wrap(err, "error reading email") diff --git a/cmd/fleetctl/preview.go b/cmd/fleetctl/preview.go index 6aae94f44b..1372f5a134 100644 --- a/cmd/fleetctl/preview.go +++ b/cmd/fleetctl/preview.go @@ -106,7 +106,7 @@ Use the stop and reset subcommands to manage the server and dependencies once st fmt.Println("Initializing server...") const ( address = "https://localhost:8412" - username = "admin" + email = "admin@example.com" password = "admin123#" ) @@ -115,7 +115,7 @@ Use the stop and reset subcommands to manage the server and dependencies once st return errors.Wrap(err, "Error creating Fleet API client handler") } - token, err := fleet.Setup(username, username, password, "Fleet Preview") + token, err := fleet.Setup(email, "Admin", password, "Fleet Preview") if err != nil { switch errors.Cause(err).(type) { case service.SetupAlreadyErr: @@ -129,7 +129,7 @@ Use the stop and reset subcommands to manage the server and dependencies once st contextConfig := Context{ Address: address, - Email: username, + Email: email, Token: token, TLSSkipVerify: true, } @@ -152,7 +152,7 @@ Use the stop and reset subcommands to manage the server and dependencies once st } fmt.Println("Fleet UI is now available at http://localhost:1337.") - fmt.Println("Username:", username) + fmt.Println("Email:", email) fmt.Println("Password:", password) // Create client and get enroll secret @@ -161,7 +161,7 @@ Use the stop and reset subcommands to manage the server and dependencies once st return errors.Wrap(err, "Error making fleetctl client") } - token, err = client.Login(username, password) + token, err = client.Login(email, password) if err != nil { return errors.Wrap(err, "fleetctl login failed") } diff --git a/cmd/fleetctl/setup.go b/cmd/fleetctl/setup.go index 53b912d15a..a576d61b0a 100644 --- a/cmd/fleetctl/setup.go +++ b/cmd/fleetctl/setup.go @@ -13,7 +13,7 @@ import ( func setupCommand() *cli.Command { var ( flEmail string - flUsername string + flName string flPassword string flOrgName string ) @@ -27,14 +27,16 @@ func setupCommand() *cli.Command { EnvVars: []string{"EMAIL"}, Value: "", Destination: &flEmail, - Usage: "Email of the admin user to create", + Usage: "Email of the admin user to create (required)", + Required: true, }, &cli.StringFlag{ - Name: "username", - EnvVars: []string{"USERNAME"}, + Name: "name", + EnvVars: []string{"NAME"}, Value: "", - Destination: &flUsername, - Usage: "Username of the admin user to create", + Destination: &flName, + Usage: "Name or nickname of the admin user to create (required)", + Required: true, }, &cli.StringFlag{ Name: "password", @@ -48,7 +50,8 @@ func setupCommand() *cli.Command { EnvVars: []string{"ORG_NAME"}, Value: "", Destination: &flOrgName, - Usage: "Name of the organization", + Usage: "Name of the organization (required)", + Required: true, }, configFlag(), contextFlag(), @@ -60,13 +63,6 @@ func setupCommand() *cli.Command { return err } - if flEmail == "" { - return errors.Errorf("Email of the admin user to create must be provided") - } - if flUsername == "" { - fmt.Println("No username supplied, using email as username") - flUsername = flEmail - } if flPassword == "" { fmt.Print("Password: ") passBytes, err := terminal.ReadPassword(int(os.Stdin.Fd())) @@ -88,7 +84,7 @@ func setupCommand() *cli.Command { } - token, err := fleet.Setup(flEmail, flUsername, flPassword, flOrgName) + token, err := fleet.Setup(flEmail, flName, flPassword, flOrgName) if err != nil { switch err.(type) { case service.SetupAlreadyErr: diff --git a/cmd/fleetctl/user.go b/cmd/fleetctl/user.go index b46b44d29e..4611aeea59 100644 --- a/cmd/fleetctl/user.go +++ b/cmd/fleetctl/user.go @@ -18,9 +18,9 @@ const ( adminFlagName = "admin" globalRoleFlagName = "global-role" teamFlagName = "team" - usernameFlagName = "username" passwordFlagName = "password" emailFlagName = "email" + nameFlagName = "name" ssoFlagName = "sso" apiOnlyFlagName = "api-only" ) @@ -44,13 +44,13 @@ func createUserCommand() *cli.Command { If a password is required and not provided by flag, the command will prompt for password input through stdin.`, Flags: []cli.Flag{ &cli.StringFlag{ - Name: usernameFlagName, - Usage: "Username for new user (required)", + Name: emailFlagName, + Usage: "Email for new user (required)", Required: true, }, &cli.StringFlag{ - Name: emailFlagName, - Usage: "Email for new user (required)", + Name: nameFlagName, + Usage: "User's full name or nickname (required)", Required: true, }, &cli.StringFlag{ @@ -85,9 +85,9 @@ func createUserCommand() *cli.Command { return err } - username := c.String(usernameFlagName) password := c.String(passwordFlagName) email := c.String(emailFlagName) + name := c.String(nameFlagName) sso := c.Bool(ssoFlagName) apiOnly := c.Bool(apiOnlyFlagName) globalRoleString := c.String(globalRoleFlagName) @@ -154,9 +154,9 @@ func createUserCommand() *cli.Command { // the user will be stuck in a bad state and not be able to log in. force_reset := !sso err = client.CreateUser(fleet.UserPayload{ - Username: &username, Password: &password, Email: &email, + Name: &name, SSOEnabled: &sso, AdminForcedPasswordReset: &force_reset, APIOnly: &apiOnly, diff --git a/cypress/integration/all/app/activateuser.spec.ts b/cypress/integration/all/app/activateuser.spec.ts index f4c4d6dbee..0a2ca9aab8 100644 --- a/cypress/integration/all/app/activateuser.spec.ts +++ b/cypress/integration/all/app/activateuser.spec.ts @@ -39,9 +39,9 @@ describe("User invite and activation", () => { cy.visit(inviteLink); - cy.findByLabelText(/username/i) + cy.findByLabelText(/full name/i) .click() - .type("ash.ketchum"); + .type("{selectall}{backspace}Ash Ketchum"); // ^$ exact match cy.findByLabelText(/^password$/i) diff --git a/cypress/integration/all/setup/setup.spec.ts b/cypress/integration/all/setup/setup.spec.ts index bc0ab0d1ac..b781b81d97 100644 --- a/cypress/integration/all/setup/setup.spec.ts +++ b/cypress/integration/all/setup/setup.spec.ts @@ -10,7 +10,9 @@ describe("Setup", () => { cy.contains(/setup/i); // Page 1 - cy.findByPlaceholderText(/username/i).type("test"); + cy.findByPlaceholderText(/full name/i).type("Test name"); + + cy.findByPlaceholderText(/email/i).type("test@example.com"); cy.findByPlaceholderText(/^password/i) .first() @@ -20,8 +22,6 @@ describe("Setup", () => { .last() .type("admin123#"); - cy.findByPlaceholderText(/email/i).type("test@example.com"); - cy.contains("button:enabled", /next/i).click(); // Page 2 diff --git a/cypress/support/commands.ts b/cypress/support/commands.ts index 2e977bc6df..15c8da7305 100644 --- a/cypress/support/commands.ts +++ b/cypress/support/commands.ts @@ -31,10 +31,10 @@ Cypress.Commands.add("setup", () => { cy.exec("make e2e-reset-db e2e-setup", { timeout: 20000 }); }); -Cypress.Commands.add("login", (username, password) => { - username ||= "admin"; +Cypress.Commands.add("login", (email, password) => { + email ||= "admin@example.com"; password ||= "user123#"; - cy.request("POST", "/api/v1/fleet/login", { username, password }).then( + cy.request("POST", "/api/v1/fleet/login", { email, password }).then( (resp) => { window.localStorage.setItem("FLEET::auth_token", resp.body.token); } @@ -222,14 +222,14 @@ Cypress.Commands.add("seedFigma", () => { }); }); -Cypress.Commands.add("addUser", (username, options = {}) => { +Cypress.Commands.add("addUser", (options = {}) => { let { password, email, globalRole } = options; password ||= "test123#"; - email ||= `${username}@example.com`; + email ||= `admin@example.com`; globalRole ||= "admin"; cy.exec( - `./build/fleetctl user create --context e2e --username "${username}" --password "${password}" --email "${email}" --global-role "${globalRole}"`, + `./build/fleetctl user create --context e2e --password "${password}" --email "${email}" --global-role "${globalRole}"`, { timeout: 5000 } ); }); diff --git a/cypress/support/index.d.ts b/cypress/support/index.d.ts index 392854e681..009b42a4b8 100644 --- a/cypress/support/index.d.ts +++ b/cypress/support/index.d.ts @@ -11,7 +11,7 @@ declare namespace Cypress { /** * Custom command to login the user programmatically using the fleet API. */ - login(username?: string, password?: string): Chainable; + login(email?: string, password?: string): Chainable; /** * Custom command to log out the current user. @@ -26,10 +26,11 @@ declare namespace Cypress { /** * Custom command to add a new user in Fleet (via fleetctl). */ - addUser( - username: string, - options?: { username?: string; password?: string; globalRole?: string } - ): Chainable; + addUser(options?: { + email?: string; + password?: string; + globalRole?: string; + }): Chainable; /** * Custom command to setup the SMTP configuration for this testing environment. diff --git a/docs/1-Using-Fleet/2-fleetctl-CLI.md b/docs/1-Using-Fleet/2-fleetctl-CLI.md index 7645d1b46a..1831f65bbf 100644 --- a/docs/1-Using-Fleet/2-fleetctl-CLI.md +++ b/docs/1-Using-Fleet/2-fleetctl-CLI.md @@ -72,7 +72,7 @@ fleetctl config set --address https://fleet.corp.example.com Now that we've configured our local CLI context, lets go ahead and create our admin account: ``` -fleetctl setup --email mike@arpaia.co +fleetctl setup --email zwass@example.com --name 'Zach' --org-name 'Fleet Test' Password: [+] Fleet setup successful and context configured! ``` @@ -558,7 +558,7 @@ spec: Fleet supports osquery's file carving functionality as of Fleet 3.3.0. This allows the Fleet server to request files (and sets of files) from osquery agents, returning the full contents to Fleet. -File carving data can be either stored in Fleet's database or to an external S3 bucket. For information on how to configure the latter, consult the [configuration docs](https://github.com/fleetdm/fleet/blob/master/docs/3-Deployment/2-Configuration.md#s3-file-carving-backend). +File carving data can be either stored in Fleet's database or to an external S3 bucket. For information on how to configure the latter, consult the [configuration docs](../3-Deployment/2-Configuration.md#s3-file-carving-backend). ### Configuration diff --git a/docs/1-Using-Fleet/3-REST-API.md b/docs/1-Using-Fleet/3-REST-API.md index 53534873af..c272d5fdd1 100644 --- a/docs/1-Using-Fleet/3-REST-API.md +++ b/docs/1-Using-Fleet/3-REST-API.md @@ -72,7 +72,7 @@ Then, use that API token to authenticate all subsequent API requests by sending Authorization: Bearer ``` -> For SSO users, username/password login is disabled. The API token can instead be retrieved from the "My account" page in the UI (/profile). On this page, choose "Get API token". +> For SSO users, email/password login is disabled. The API token can instead be retrieved from the "My account" page in the UI (/profile). On this page, choose "Get API token". ### Log in @@ -80,13 +80,13 @@ Authenticates the user with the specified credentials. Use the token returned fr `POST /api/v1/fleet/login` -> This API endpoint is not available to SSO users, since username/password login is disabled for SSO users. To get an API token for an SSO user, you can use the Fleet UI. +> This API endpoint is not available to SSO users, since email/password login is disabled for SSO users. To get an API token for an SSO user, you can use the Fleet UI. #### Parameters | Name | Type | In | Description | | -------- | ------ | ---- | --------------------------------------------- | -| username | string | body | **Required**. The user's email. | +| email | string | body | **Required**. The user's email. | | password | string | body | **Required**. The user's plain text password. | #### Example @@ -97,7 +97,7 @@ Authenticates the user with the specified credentials. Use the token returned fr ``` { - "username": "janedoe@example.com", + "email": "janedoe@example.com", "password": "VArCjNW7CfsxGp67" } ``` @@ -112,8 +112,7 @@ Authenticates the user with the specified credentials. Use the token returned fr "created_at": "2020-11-13T22:57:12Z", "updated_at": "2020-11-13T22:57:12Z", "id": 1, - "username": "jane", - "name": "", + "name": "Jane Doe", "email": "janedoe@example.com", "enabled": true, "force_password_reset": false, @@ -294,8 +293,7 @@ Retrieves the user data for the authenticated user. "created_at": "2020-11-13T22:57:12Z", "updated_at": "2020-11-16T23:49:41Z", "id": 1, - "username": "jane", - "name": "", + "name": "Jane Doe", "email": "janedoe@example.com", "global_role": "admin", "enabled": true, @@ -337,8 +335,7 @@ Resets the password of the authenticated user. Requires that `force_password_res "created_at": "2020-11-13T22:57:12Z", "updated_at": "2020-11-17T00:09:23Z", "id": 1, - "username": "jane", - "name": "", + "name": "Jane Doe", "email": "janedoe@example.com", "enabled": true, "force_password_reset": false, @@ -1380,8 +1377,7 @@ None. "created_at": "2020-12-10T03:52:53Z", "updated_at": "2020-12-10T03:52:53Z", "id": 1, - "username": "janedoe", - "name": "", + "name": "Jane Doe", "email": "janedoe@example.com", "global_role": null, "enabled": true, @@ -1413,7 +1409,7 @@ None. "errors": [ { "name": "base", - "reason": "username or email and password do not match" + "reason": "Authentication failed" } ] } @@ -1432,7 +1428,6 @@ Creates a user account after an invited user provides registration information a | email | string | body | **Required**. The email address of the user. | | invite_token | string | body | **Required**. Token provided to the user in the invitation email. | | name | string | body | The name of the user. | -| username | string | body | **Required**. The username chosen by the user | | password | string | body | **Required**. The password chosen by the user. | | password_confirmation | string | body | **Required**. Confirmation of the password chosen by the user. | | global_role | string | body | The role assigned to the user. In Fleet 4.0.0, 3 user roles were introduced (`admin`, `maintainer`, and `observer`). If `global_role` is specified, `teams` cannot be specified. | @@ -1449,7 +1444,6 @@ Creates a user account after an invited user provides registration information a "email": "janedoe@example.com", "invite_token": "SjdReDNuZW5jd3dCbTJtQTQ5WjJTc2txWWlEcGpiM3c=", "name": "janedoe", - "username": "janedoe", "password": "test-123", "password_confirmation": "test-123", "teams": [ @@ -1475,7 +1469,6 @@ Creates a user account after an invited user provides registration information a "created_at": "0001-01-01T00:00:00Z", "updated_at": "0001-01-01T00:00:00Z", "id": 2, - "username": "janedoe", "name": "janedoe", "email": "janedoe@example.com", "enabled": true, @@ -1498,7 +1491,7 @@ Creates a user account after an invited user provides registration information a "errors": [ { "name": "base", - "reason": "username or email and password do not match" + "reason": "Authentication failed" } ] } @@ -1531,7 +1524,7 @@ The same error will be returned whenever one of the required parameters fails th "message": "Validation Failed", "errors": [ { - "name": "username", + "name": "name", "reason": "cannot be empty" } ] @@ -1548,7 +1541,6 @@ Creates a user account without requiring an invitation, the user is enabled imme | Name | Type | In | Description | | ----------- | ------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| username | string | body | **Required**. The user's username. | | email | string | body | **Required**. The user's email address. | | password | string | body | **Required**. The user's password. | | api_only | boolean | body | User is an "API-only" user (cannot use web UI) if true. | @@ -1563,17 +1555,17 @@ Creates a user account without requiring an invitation, the user is enabled imme ``` { - "username": "janedoe", + "name": "Jane Doe", "email": "janedoe@example.com", "password": "test-123", "teams": [ { - “id”: 2, - “role: “observer” + "id": 2, + "role: "observer" }, { - “id”: 3, - “role: “maintainer” + "id": 3, + "role: "maintainer" }, ] } @@ -1589,8 +1581,7 @@ Creates a user account without requiring an invitation, the user is enabled imme "created_at": "0001-01-01T00:00:00Z", "updated_at": "0001-01-01T00:00:00Z", "id": 5, - "username": "janedoe", - "name": "", + "name": "Jane Doe", "email": "janedoe@example.com", "enabled": true, "force_password_reset": false, @@ -1600,34 +1591,18 @@ Creates a user account without requiring an invitation, the user is enabled imme "global_role": null, "teams": [ { - “id”: 2, - “role: “observer” + "id": 2, + "role: "observer" }, { - “id”: 3, - “role: “maintainer” + "id": 3, + "role: "maintainer" }, ] } } ``` -##### Failed authentication - -`Status: 401 Authentication Failed` - -``` -{ - "message": "Authentication Failed", - "errors": [ - { - "name": "base", - "reason": "username or email and password do not match" - } - ] -} -``` - ##### User doesn't exist `Status: 404 Resource Not Found` @@ -1678,8 +1653,7 @@ Returns all information about a specific user. "created_at": "2020-12-10T05:20:25Z", "updated_at": "2020-12-10T05:24:27Z", "id": 2, - "username": "janedoe", - "name": "janedoe", + "name": "Jane Doe", "email": "janedoe@example.com", "global_role": "admin", "enabled": true, @@ -1691,22 +1665,6 @@ Returns all information about a specific user. } ``` -##### Failed authentication - -`Status: 401 Authentication Failed` - -``` -{ - "message": "Authentication Failed", - "errors": [ - { - "name": "base", - "reason": "username or email and password do not match" - } - ] -} -``` - ##### User doesn't exist `Status: 404 Resource Not Found` @@ -1733,7 +1691,6 @@ Returns all information about a specific user. | ----------- | ------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | id | integer | path | **Required**. The user's id. | | name | string | body | The user's name. | -| username | string | body | The user's username. | | position | string | body | The user's position. | | email | string | body | The user's email. | | sso_enabled | boolean | body | Whether or not SSO is enabled for the user. | @@ -1764,7 +1721,6 @@ Returns all information about a specific user. "created_at": "2021-02-03T16:11:06Z", "updated_at": "2021-02-03T16:11:06Z", "id": 2, - "username": "jdoe", "name": "Jane Doe", "email": "janedoe@example.com", "global_role": "admin", @@ -1785,14 +1741,14 @@ Returns all information about a specific user. ``` { - “teams”: [ + "teams": [ { - “id”: 1, - “role: “observer” + "id": 1, + "role: "observer" }, { - “id”: 2 - “role”: “maintainer” + "id": 2 + "role": "maintainer" } ] } @@ -1808,7 +1764,6 @@ Returns all information about a specific user. "created_at": "2021-02-03T16:11:06Z", "updated_at": "2021-02-03T16:11:06Z", "id": 2, - "username": "jdoe", "name": "Jane Doe", "email": "janedoe@example.com", "enabled": true, @@ -1818,12 +1773,12 @@ Returns all information about a specific user. "global_role": "admin" "teams": [ { - “id”: 2, - “role: “observer” + "id": 2, + "role: "observer" }, { - “id”: 3, - “role: “maintainer” + "id": 3, + "role: "maintainer" }, ] } @@ -1889,7 +1844,6 @@ The selected user is logged out of Fleet and required to reset their password du "created_at": "2021-02-23T22:23:34Z", "updated_at": "2021-02-23T22:28:52Z", "id": 2, - "username": "janedoe", "name": "Jane Doe", "email": "janedoe@example.com", "force_password_reset": true, @@ -4378,12 +4332,12 @@ None. "global_role": "admin" "teams": [ { - “id”: 2, - “role: “observer” + "id": 2, + "role: "observer" }, { - “id”: 3, - “role: “maintainer” + "id": 3, + "role: "maintainer" }, ] } @@ -4406,12 +4360,12 @@ None. "sso_enabled": false, "teams": [ { - “id”: 2, - “role: “observer” + "id": 2, + "role: "observer" }, { - “id”: 3, - “role: “maintainer” + "id": 3, + "role: "maintainer" }, ] } @@ -4736,13 +4690,13 @@ _Available in Fleet Basic_ { "teams: [ { - “name”: “workstations”, - “id”: 1. - “user_ids”: [], - “host_ids”: [], + "name": "workstations", + "id": 1. + "user_ids": [], + "host_ids": [], "user_count": 0, "host_count": 0, - “agent_options”: { + "agent_options": { "spec": { "config": { "options": { @@ -4767,13 +4721,13 @@ _Available in Fleet Basic_ } }, { - “name”: "servers", - “id”: 2, - “user_ids”: [], - “host_ids”: [], + "name": "servers", + "id": 2, + "user_ids": [], + "host_ids": [], "user_count": 0, "host_count": 0, - “agent_options”: { + "agent_options": { "spec": { "config": { "options": { @@ -4833,13 +4787,13 @@ _Available in Fleet Basic_ { "teams: [ { - “name”: “workstations”, - “id”: 1 - “user_ids”: [], - “host_ids”: [], + "name": "workstations", + "id": 1 + "user_ids": [], + "host_ids": [], "user_count": 0, "host_count": 0, - “agent_options”: { + "agent_options": { "spec": { "config": { "options": { @@ -4901,13 +4855,13 @@ _Available in Fleet Basic_ ``` { "team": { - “name”: “Workstations”, - “id”: 1 - “user_ids”: [1, 17, 22, 32], - “host_ids”: [], + "name": "Workstations", + "id": 1 + "user_ids": [1, 17, 22, 32], + "host_ids": [], "user_count": 4, "host_count": 0, - “agent_options”: { + "agent_options": { "spec": { "config": { "options": { @@ -4953,13 +4907,13 @@ _Available in Fleet Basic_ ``` { "team": { - “name”: “Workstations”, - “id”: 1 - “user_ids”: [1, 17, 22, 32], - “host_ids”: [3, 6, 7, 8, 9, 20, 32, 44], + "name": "Workstations", + "id": 1 + "user_ids": [1, 17, 22, 32], + "host_ids": [3, 6, 7, 8, 9, 20, 32, 44], "user_count": 4, "host_count": 8, - “agent_options”: { + "agent_options": { "spec": { "config": { "options": { @@ -4994,7 +4948,7 @@ _Available in Fleet Basic_ ``` { - “agent_options”: { + "agent_options": { "spec": { "config": { "options": { @@ -5027,13 +4981,13 @@ _Available in Fleet Basic_ ``` { "team": { - “name”: “Workstations”, - “id”: 1 - “user_ids”: [1, 17, 22, 32], - “host_ids”: [3, 6, 7, 8, 9, 20, 32, 44], + "name": "Workstations", + "id": 1 + "user_ids": [1, 17, 22, 32], + "host_ids": [3, 6, 7, 8, 9, 20, 32, 44], "user_count": 4, "host_count": 8, - “agent_options”: { + "agent_options": { "spec": { "config": { "options": { diff --git a/docs/1-Using-Fleet/FAQ.md b/docs/1-Using-Fleet/FAQ.md index 50ea9b892b..8b1bbae8c3 100644 --- a/docs/1-Using-Fleet/FAQ.md +++ b/docs/1-Using-Fleet/FAQ.md @@ -31,7 +31,7 @@ It’s standard deployment practice to have multiple Fleet servers behind a load ## Can I target my hosts using their enroll secrets? -No, currently, there’s no way to retrieve the name of the enroll secret with a query. This means that there's no way to create a label using your hosts' enroll secrets and then use this label as a target for queries or query packs. +No, currently, there’s no way to retrieve the name of the enroll secret with a query. This means that there's no way to create a label using your hosts' enroll secrets and then use this label as a target for queries or query packs. Typically folks will use some other unique identifier to create labels that distinguish each type of device. As a workaround, [Fleet's manual labels](./2-fleetctl-CLI.md#host-labels) provide a way to create groups of hosts without a query. These manual labels can then be used as targets for queries or query packs. @@ -39,7 +39,7 @@ In the coming months, Fleet will introduce the [Teams feature](https://github.co ## How often do labels refresh? Is the refresh frequency configurable? -The update frequency for labels is configurable with the [—osquery_label_update_interval](https://github.com/fleetdm/fleet/blob/master/docs/3-Deployment/2-Configuration.md#osquery_label_update_interval) flag (default 1 hour). +The update frequency for labels is configurable with the [—osquery_label_update_interval](../3-Deployment/2-Configuration.md#osquery_label_update_interval) flag (default 1 hour). ## How do I revoke the authorization tokens for a user? @@ -66,7 +66,7 @@ Some folks like to enforce users with SAML SSO enabled to login only via the SSO There is no option in the Fleet UI for disabling password-based authentication. However, users that have SSO enabled in Fleet will not be able to log in via password-based authentication. -If a user has SSO enabled, the Login page in the Fleet UI does displays the “Username” and “Password” fields but on attempted password-based login, this user will receive an “Authentication failed” message. +If a user has SSO enabled, the Login page in the Fleet UI does displays the “Email” and “Password” fields but on attempted password-based login, this user will receive an “Authentication failed” message. ## Where are my query results? @@ -84,7 +84,7 @@ It is possible to configure osqueryd to log query results outside of Fleet. For Folks typically use Fleet to ship logs to data aggregation systems like Splunk, the ELK stack, and Graylog. -The [logger configuration options](https://github.com/fleetdm/fleet/blob/master/docs/3-Deployment/2-Configuration.md#osquery_status_log_plugin) allow you to select the log output plugin. Using the log outputs you can route the logs to your chosen aggregation system. +The [logger configuration options](../3-Deployment/2-Configuration.md#osquery_status_log_plugin) allow you to select the log output plugin. Using the log outputs you can route the logs to your chosen aggregation system. ### Troubleshooting @@ -114,15 +114,15 @@ The ability to view each host’s installed software was released behind a featu Once the Software inventory feature is turned on, a list of a specific host’s installed software is available using the `api/v1/fleet/hosts/{id}` endpoint. [Check out the documentation for this endpoint](./3-REST-API.md#get-host). -It’s possible in Fleet to retrieve each host’s kernel version, using the Fleet API, through `additional_queries`. The Fleet configuration options yaml file includes an `additional_queries` property that allows you to append custom query results to the host details returned by the `api/v1/fleet/hosts` endpoint. [Check out an example configuration file with the additional_queries field](./2-fleetctl-CLI.md#fleet-configuration-options). +It’s possible in Fleet to retrieve each host’s kernel version, using the Fleet API, through `additional_queries`. The Fleet configuration options yaml file includes an `additional_queries` property that allows you to append custom query results to the host details returned by the `api/v1/fleet/hosts` endpoint. [Check out an example configuration file with the additional_queries field](./2-fleetctl-CLI.md#fleet-configuration-options). ## How do I automatically add hosts to packs when the hosts enroll to Fleet? You can accomplish this by adding specific labels as targets of your pack. First, identify an already existing label or create a new label that will include the hosts you intend to enroll to Fleet. Next, add this label as a target of the pack in the Fleet UI. -When your hosts enroll to Fleet, they will become a member of the label and, because the label is a target of your pack, these hosts will automatically become targets of the pack. +When your hosts enroll to Fleet, they will become a member of the label and, because the label is a target of your pack, these hosts will automatically become targets of the pack. -You can also do this by setting the `targets` field in the [YAML configuration file](./2-fleetctl-CLI.md#query-packs) that manages the packs that are added to your Fleet instance. +You can also do this by setting the `targets` field in the [YAML configuration file](./2-fleetctl-CLI.md#query-packs) that manages the packs that are added to your Fleet instance. ## How do I resolve an "unknown column" error when upgrading Fleet? diff --git a/frontend/components/forms/ConfirmInviteForm/ConfirmInviteForm.jsx b/frontend/components/forms/ConfirmInviteForm/ConfirmInviteForm.jsx index 54c9f000ee..cbdd83ef66 100644 --- a/frontend/components/forms/ConfirmInviteForm/ConfirmInviteForm.jsx +++ b/frontend/components/forms/ConfirmInviteForm/ConfirmInviteForm.jsx @@ -7,7 +7,7 @@ import Button from "components/buttons/Button"; import InputFieldWithIcon from "components/forms/fields/InputFieldWithIcon"; import helpers from "./helpers"; -const formFields = ["name", "username", "password", "password_confirmation"]; +const formFields = ["name", "password", "password_confirmation"]; const { validate } = helpers; class ConfirmInviteForm extends Component { @@ -16,7 +16,6 @@ class ConfirmInviteForm extends Component { className: PropTypes.string, fields: PropTypes.shape({ name: formFieldInterface.isRequired, - username: formFieldInterface.isRequired, password: formFieldInterface.isRequired, password_confirmation: formFieldInterface.isRequired, }).isRequired, @@ -35,7 +34,6 @@ class ConfirmInviteForm extends Component { autofocus placeholder="Full Name" /> - { .find("input"); const passwordInput = form.find({ name: "password" }).find("input"); const submitBtn = form.find("button"); - const usernameInput = form.find({ name: "username" }).find("input"); it("renders", () => { expect(form.length).toEqual(1); @@ -41,7 +40,6 @@ describe("ConfirmInviteForm - component", () => { it("calls the handleSubmit prop with the invite_token when valid", () => { fillInFormInput(nameInput, "Gnar Dog"); - fillInFormInput(usernameInput, "gnardog"); fillInFormInput(passwordInput, "p@ssw0rd"); fillInFormInput(passwordConfirmationInput, "p@ssw0rd"); submitBtn.simulate("click"); @@ -49,7 +47,6 @@ describe("ConfirmInviteForm - component", () => { expect(handleSubmitSpy).toHaveBeenCalledWith({ ...formData, name: "Gnar Dog", - username: "gnardog", password: "p@ssw0rd", password_confirmation: "p@ssw0rd", }); @@ -72,23 +69,6 @@ describe("ConfirmInviteForm - component", () => { }); }); - describe("username input", () => { - it("changes form state on change", () => { - fillInFormInput(usernameInput, "gnardog"); - - expect(form.state().formData).toMatchObject({ username: "gnardog" }); - }); - - it("validates the field must be present", () => { - fillInFormInput(usernameInput, ""); - submitBtn.simulate("click"); - - expect(form.state().errors).toMatchObject({ - username: "Username must be present", - }); - }); - }); - describe("password input", () => { it("changes form state on change", () => { fillInFormInput(passwordInput, "p@ssw0rd"); diff --git a/frontend/components/forms/ConfirmInviteForm/helpers.js b/frontend/components/forms/ConfirmInviteForm/helpers.js index 91304cf350..8ae978b640 100644 --- a/frontend/components/forms/ConfirmInviteForm/helpers.js +++ b/frontend/components/forms/ConfirmInviteForm/helpers.js @@ -7,17 +7,12 @@ const validate = (formData) => { name, password, password_confirmation: passwordConfirmation, - username, } = formData; if (!name) { errors.name = "Full name must be present"; } - if (!username) { - errors.username = "Username must be present"; - } - if ( password && passwordConfirmation && diff --git a/frontend/components/forms/ConfirmSSOInviteForm/ConfirmSSOInviteForm.jsx b/frontend/components/forms/ConfirmSSOInviteForm/ConfirmSSOInviteForm.jsx index 45b807fdc8..c0f3309cda 100644 --- a/frontend/components/forms/ConfirmSSOInviteForm/ConfirmSSOInviteForm.jsx +++ b/frontend/components/forms/ConfirmSSOInviteForm/ConfirmSSOInviteForm.jsx @@ -7,7 +7,7 @@ import Button from "components/buttons/Button"; import InputFieldWithIcon from "components/forms/fields/InputFieldWithIcon"; import helpers from "./helpers"; -const formFields = ["name", "username", "password", "password_confirmation"]; +const formFields = ["name", "password", "password_confirmation"]; const { validate } = helpers; class ConfirmSSOInviteForm extends Component { @@ -16,7 +16,6 @@ class ConfirmSSOInviteForm extends Component { className: PropTypes.string, fields: PropTypes.shape({ name: formFieldInterface.isRequired, - username: formFieldInterface.isRequired, password: formFieldInterface.isRequired, password_confirmation: formFieldInterface.isRequired, }).isRequired, @@ -35,7 +34,6 @@ class ConfirmSSOInviteForm extends Component { autofocus placeholder="Full Name" /> -