code.gitea.io/gitea@v1.21.7/tests/integration/user_test.go (about)

     1  // Copyright 2017 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package integration
     5  
     6  import (
     7  	"net/http"
     8  	"testing"
     9  
    10  	auth_model "code.gitea.io/gitea/models/auth"
    11  	issues_model "code.gitea.io/gitea/models/issues"
    12  	repo_model "code.gitea.io/gitea/models/repo"
    13  	"code.gitea.io/gitea/models/unittest"
    14  	user_model "code.gitea.io/gitea/models/user"
    15  	"code.gitea.io/gitea/modules/setting"
    16  	api "code.gitea.io/gitea/modules/structs"
    17  	"code.gitea.io/gitea/modules/test"
    18  	"code.gitea.io/gitea/modules/translation"
    19  	"code.gitea.io/gitea/tests"
    20  
    21  	"github.com/stretchr/testify/assert"
    22  )
    23  
    24  func TestViewUser(t *testing.T) {
    25  	defer tests.PrepareTestEnv(t)()
    26  
    27  	req := NewRequest(t, "GET", "/user2")
    28  	MakeRequest(t, req, http.StatusOK)
    29  }
    30  
    31  func TestRenameUsername(t *testing.T) {
    32  	defer tests.PrepareTestEnv(t)()
    33  
    34  	session := loginUser(t, "user2")
    35  	req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
    36  		"_csrf":    GetCSRF(t, session, "/user/settings"),
    37  		"name":     "newUsername",
    38  		"email":    "user2@example.com",
    39  		"language": "en-US",
    40  	})
    41  	session.MakeRequest(t, req, http.StatusSeeOther)
    42  
    43  	unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "newUsername"})
    44  	unittest.AssertNotExistsBean(t, &user_model.User{Name: "user2"})
    45  }
    46  
    47  func TestRenameInvalidUsername(t *testing.T) {
    48  	defer tests.PrepareTestEnv(t)()
    49  
    50  	invalidUsernames := []string{
    51  		"%2f*",
    52  		"%2f.",
    53  		"%2f..",
    54  		"%00",
    55  		"thisHas ASpace",
    56  		"p<A>tho>lo<gical",
    57  		".",
    58  		"..",
    59  		".well-known",
    60  		".abc",
    61  		"abc.",
    62  		"a..bc",
    63  		"a...bc",
    64  		"a.-bc",
    65  		"a._bc",
    66  		"a_-bc",
    67  		"a/bc",
    68  		"☁️",
    69  		"-",
    70  		"--diff",
    71  		"-im-here",
    72  		"a space",
    73  	}
    74  
    75  	session := loginUser(t, "user2")
    76  	for _, invalidUsername := range invalidUsernames {
    77  		t.Logf("Testing username %s", invalidUsername)
    78  
    79  		req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
    80  			"_csrf": GetCSRF(t, session, "/user/settings"),
    81  			"name":  invalidUsername,
    82  			"email": "user2@example.com",
    83  		})
    84  		resp := session.MakeRequest(t, req, http.StatusOK)
    85  		htmlDoc := NewHTMLParser(t, resp.Body)
    86  		assert.Contains(t,
    87  			htmlDoc.doc.Find(".ui.negative.message").Text(),
    88  			translation.NewLocale("en-US").Tr("form.username_error"),
    89  		)
    90  
    91  		unittest.AssertNotExistsBean(t, &user_model.User{Name: invalidUsername})
    92  	}
    93  }
    94  
    95  func TestRenameReservedUsername(t *testing.T) {
    96  	defer tests.PrepareTestEnv(t)()
    97  
    98  	reservedUsernames := []string{
    99  		// ".", "..", ".well-known", // The names are not only reserved but also invalid
   100  		"admin",
   101  		"api",
   102  		"assets",
   103  		"attachments",
   104  		"avatar",
   105  		"avatars",
   106  		"captcha",
   107  		"commits",
   108  		"debug",
   109  		"error",
   110  		"explore",
   111  		"favicon.ico",
   112  		"ghost",
   113  		"issues",
   114  		"login",
   115  		"manifest.json",
   116  		"metrics",
   117  		"milestones",
   118  		"new",
   119  		"notifications",
   120  		"org",
   121  		"pulls",
   122  		"raw",
   123  		"repo",
   124  		"repo-avatars",
   125  		"robots.txt",
   126  		"search",
   127  		"serviceworker.js",
   128  		"ssh_info",
   129  		"swagger.v1.json",
   130  		"user",
   131  		"v2",
   132  	}
   133  
   134  	session := loginUser(t, "user2")
   135  	for _, reservedUsername := range reservedUsernames {
   136  		t.Logf("Testing username %s", reservedUsername)
   137  		req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
   138  			"_csrf":    GetCSRF(t, session, "/user/settings"),
   139  			"name":     reservedUsername,
   140  			"email":    "user2@example.com",
   141  			"language": "en-US",
   142  		})
   143  		resp := session.MakeRequest(t, req, http.StatusSeeOther)
   144  
   145  		req = NewRequest(t, "GET", test.RedirectURL(resp))
   146  		resp = session.MakeRequest(t, req, http.StatusOK)
   147  		htmlDoc := NewHTMLParser(t, resp.Body)
   148  		assert.Contains(t,
   149  			htmlDoc.doc.Find(".ui.negative.message").Text(),
   150  			translation.NewLocale("en-US").Tr("user.form.name_reserved", reservedUsername),
   151  		)
   152  
   153  		unittest.AssertNotExistsBean(t, &user_model.User{Name: reservedUsername})
   154  	}
   155  }
   156  
   157  func TestExportUserGPGKeys(t *testing.T) {
   158  	defer tests.PrepareTestEnv(t)()
   159  	// Export empty key list
   160  	testExportUserGPGKeys(t, "user1", `-----BEGIN PGP PUBLIC KEY BLOCK-----
   161  Note: This user hasn't uploaded any GPG keys.
   162  
   163  
   164  =twTO
   165  -----END PGP PUBLIC KEY BLOCK-----
   166  `)
   167  	// Import key
   168  	// User1 <user1@example.com>
   169  	session := loginUser(t, "user1")
   170  	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser)
   171  	testCreateGPGKey(t, session.MakeRequest, token, http.StatusCreated, `-----BEGIN PGP PUBLIC KEY BLOCK-----
   172  
   173  mQENBFyy/VUBCADJ7zbM20Z1RWmFoVgp5WkQfI2rU1Vj9cQHes9i42wVLLtcbPeo
   174  QzubgzvMPITDy7nfWxgSf83E23DoHQ1ACFbQh/6eFSRrjsusp3YQ/08NSfPPbcu8
   175  0M5G+VGwSfzS5uEcwBVQmHyKdcOZIERTNMtYZx1C3bjLD1XVJHvWz9D72Uq4qeO3
   176  8SR+lzp5n6ppUakcmRnxt3nGRBj1+hEGkdgzyPo93iy+WioegY2lwCA9xMEo5dah
   177  BmYxWx51zyiXYlReTaxlyb3/nuSUt8IcW3Q8zjdtJj4Nu8U1SpV8EdaA1I9IPbHW
   178  510OSLmD3XhqHH5m6mIxL1YoWxk3V7gpDROtABEBAAG0GVVzZXIxIDx1c2VyMUBl
   179  eGFtcGxlLmNvbT6JAU4EEwEIADgWIQTQEbrYxmXsp1z3j7z9+v0I6RSEHwUCXLL9
   180  VQIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRD9+v0I6RSEH22YCACFqL5+
   181  6M0m18AMC/pumcpnnmvAS1GrrKTF8nOROA1augZwp1WCNuKw2R6uOJIHANrYECSn
   182  u7+j6GBP2gbIW8mSAzS6HWCs7GGiPpVtT4wcu8wljUI6BxjpyZtoEkriyBjt6HfK
   183  rkegbkuySoJvjq4IcO5D1LB1JWgsUjMYQJj/ZpBIzVtjG9QtFSOiT1Hct4PoZHdC
   184  nsdSgyCkwRZXG+u3kT/wP9F663ba4o16vYlz3dCGo66lF2tyoG3qcyZ1OUzUrnuv
   185  96ytAzT6XIhrE0nVoBprMxFF5zExotJD3bHjcGBFNLf944bhjKee3U6t9+OsfJVC
   186  l7N5xxIawCuTQdbfuQENBFyy/VUBCADe61yGEoTwKfsOKIhxLaNoRmD883O0tiWt
   187  soO/HPj9dPQLTOiwXgSgSCd8C+LNxGKct87wgFozpah4tDLC6c0nALuHJ0SLbkfz
   188  55aRhLeOOcrAydatDp72GroXzqpZ0xZBk5wjIWdgEol2GmVRM8QGbeuakU/HVz5y
   189  lPzxUUocgdbSi3GE3zbzijQzVJdyL/kw/KP7pKT/PPKKJ2C5NQDLy0XGKEHddXGR
   190  EWKkVlRalxq/TjfaMR0bi3MpezBsQmp99ATPO/d7trayZUxQHRtXzGFiOXfDHATr
   191  qN730sODjqvU+mpc/SHCRwh9qWDjZRHSuKU5YDBjb5jIQJivZsQ/ABEBAAGJATYE
   192  GAEIACAWIQTQEbrYxmXsp1z3j7z9+v0I6RSEHwUCXLL9VQIbDAAKCRD9+v0I6RSE
   193  H7WoB/4tXl+97rQ6owPCGSVp1Xbwt2521V7COgsOFRVTRTryEWxRW8mm0S7wQvax
   194  C0TLXKur6NVYQMn01iyL+FZzRpEWNuYF3f9QeeLJ/+l2DafESNhNTy17+RPmacK6
   195  21dccpqchByVw/UMDeHSyjQLiG2lxzt8Gfx2gHmSbrq3aWovTGyz6JTffZvfy/n2
   196  0Hm437OBPazO0gZyXhdV2PE5RSUfvAgm44235tcV5EV0d32TJDfv61+Vr2GUbah6
   197  7XhJ1v6JYuh8kaYaEz8OpZDeh7f6Ho6PzJrsy/TKTKhGgZNINj1iaPFyOkQgKR5M
   198  GrE0MHOxUbc9tbtyk0F1SuzREUBH
   199  =DDXw
   200  -----END PGP PUBLIC KEY BLOCK-----
   201  `)
   202  	// Export new key
   203  	testExportUserGPGKeys(t, "user1", `-----BEGIN PGP PUBLIC KEY BLOCK-----
   204  
   205  xsBNBFyy/VUBCADJ7zbM20Z1RWmFoVgp5WkQfI2rU1Vj9cQHes9i42wVLLtcbPeo
   206  QzubgzvMPITDy7nfWxgSf83E23DoHQ1ACFbQh/6eFSRrjsusp3YQ/08NSfPPbcu8
   207  0M5G+VGwSfzS5uEcwBVQmHyKdcOZIERTNMtYZx1C3bjLD1XVJHvWz9D72Uq4qeO3
   208  8SR+lzp5n6ppUakcmRnxt3nGRBj1+hEGkdgzyPo93iy+WioegY2lwCA9xMEo5dah
   209  BmYxWx51zyiXYlReTaxlyb3/nuSUt8IcW3Q8zjdtJj4Nu8U1SpV8EdaA1I9IPbHW
   210  510OSLmD3XhqHH5m6mIxL1YoWxk3V7gpDROtABEBAAHNGVVzZXIxIDx1c2VyMUBl
   211  eGFtcGxlLmNvbT7CwI4EEwEIADgWIQTQEbrYxmXsp1z3j7z9+v0I6RSEHwUCXLL9
   212  VQIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgAAKCRD9+v0I6RSEH22YCACFqL5+
   213  6M0m18AMC/pumcpnnmvAS1GrrKTF8nOROA1augZwp1WCNuKw2R6uOJIHANrYECSn
   214  u7+j6GBP2gbIW8mSAzS6HWCs7GGiPpVtT4wcu8wljUI6BxjpyZtoEkriyBjt6HfK
   215  rkegbkuySoJvjq4IcO5D1LB1JWgsUjMYQJj/ZpBIzVtjG9QtFSOiT1Hct4PoZHdC
   216  nsdSgyCkwRZXG+u3kT/wP9F663ba4o16vYlz3dCGo66lF2tyoG3qcyZ1OUzUrnuv
   217  96ytAzT6XIhrE0nVoBprMxFF5zExotJD3bHjcGBFNLf944bhjKee3U6t9+OsfJVC
   218  l7N5xxIawCuTQdbfzsBNBFyy/VUBCADe61yGEoTwKfsOKIhxLaNoRmD883O0tiWt
   219  soO/HPj9dPQLTOiwXgSgSCd8C+LNxGKct87wgFozpah4tDLC6c0nALuHJ0SLbkfz
   220  55aRhLeOOcrAydatDp72GroXzqpZ0xZBk5wjIWdgEol2GmVRM8QGbeuakU/HVz5y
   221  lPzxUUocgdbSi3GE3zbzijQzVJdyL/kw/KP7pKT/PPKKJ2C5NQDLy0XGKEHddXGR
   222  EWKkVlRalxq/TjfaMR0bi3MpezBsQmp99ATPO/d7trayZUxQHRtXzGFiOXfDHATr
   223  qN730sODjqvU+mpc/SHCRwh9qWDjZRHSuKU5YDBjb5jIQJivZsQ/ABEBAAHCwHYE
   224  GAEIACAWIQTQEbrYxmXsp1z3j7z9+v0I6RSEHwUCXLL9VQIbDAAKCRD9+v0I6RSE
   225  H7WoB/4tXl+97rQ6owPCGSVp1Xbwt2521V7COgsOFRVTRTryEWxRW8mm0S7wQvax
   226  C0TLXKur6NVYQMn01iyL+FZzRpEWNuYF3f9QeeLJ/+l2DafESNhNTy17+RPmacK6
   227  21dccpqchByVw/UMDeHSyjQLiG2lxzt8Gfx2gHmSbrq3aWovTGyz6JTffZvfy/n2
   228  0Hm437OBPazO0gZyXhdV2PE5RSUfvAgm44235tcV5EV0d32TJDfv61+Vr2GUbah6
   229  7XhJ1v6JYuh8kaYaEz8OpZDeh7f6Ho6PzJrsy/TKTKhGgZNINj1iaPFyOkQgKR5M
   230  GrE0MHOxUbc9tbtyk0F1SuzREUBH
   231  =WFf5
   232  -----END PGP PUBLIC KEY BLOCK-----
   233  `)
   234  }
   235  
   236  func testExportUserGPGKeys(t *testing.T, user, expected string) {
   237  	session := loginUser(t, user)
   238  	t.Logf("Testing username %s export gpg keys", user)
   239  	req := NewRequest(t, "GET", "/"+user+".gpg")
   240  	resp := session.MakeRequest(t, req, http.StatusOK)
   241  	// t.Log(resp.Body.String())
   242  	assert.Equal(t, expected, resp.Body.String())
   243  }
   244  
   245  func TestGetUserRss(t *testing.T) {
   246  	user34 := "the_34-user.with.all.allowedChars"
   247  	req := NewRequestf(t, "GET", "/%s.rss", user34)
   248  	resp := MakeRequest(t, req, http.StatusOK)
   249  	if assert.EqualValues(t, "application/rss+xml;charset=utf-8", resp.Header().Get("Content-Type")) {
   250  		rssDoc := NewHTMLParser(t, resp.Body).Find("channel")
   251  		title, _ := rssDoc.ChildrenFiltered("title").Html()
   252  		assert.EqualValues(t, "Feed of &#34;the_1-user.with.all.allowedChars&#34;", title)
   253  		description, _ := rssDoc.ChildrenFiltered("description").Html()
   254  		assert.EqualValues(t, "&lt;p dir=&#34;auto&#34;&gt;some &lt;a href=&#34;https://commonmark.org/&#34; rel=&#34;nofollow&#34;&gt;commonmark&lt;/a&gt;!&lt;/p&gt;\n", description)
   255  	}
   256  }
   257  
   258  func TestListStopWatches(t *testing.T) {
   259  	defer tests.PrepareTestEnv(t)()
   260  
   261  	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
   262  	owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
   263  
   264  	session := loginUser(t, owner.Name)
   265  	req := NewRequestf(t, "GET", "/user/stopwatches")
   266  	resp := session.MakeRequest(t, req, http.StatusOK)
   267  	var apiWatches []*api.StopWatch
   268  	DecodeJSON(t, resp, &apiWatches)
   269  	stopwatch := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: owner.ID})
   270  	issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: stopwatch.IssueID})
   271  	if assert.Len(t, apiWatches, 1) {
   272  		assert.EqualValues(t, stopwatch.CreatedUnix.AsTime().Unix(), apiWatches[0].Created.Unix())
   273  		assert.EqualValues(t, issue.Index, apiWatches[0].IssueIndex)
   274  		assert.EqualValues(t, issue.Title, apiWatches[0].IssueTitle)
   275  		assert.EqualValues(t, repo.Name, apiWatches[0].RepoName)
   276  		assert.EqualValues(t, repo.OwnerName, apiWatches[0].RepoOwnerName)
   277  		assert.Greater(t, apiWatches[0].Seconds, int64(0))
   278  	}
   279  }
   280  
   281  func TestUserLocationMapLink(t *testing.T) {
   282  	setting.Service.UserLocationMapURL = "https://example/foo/"
   283  	defer tests.PrepareTestEnv(t)()
   284  
   285  	session := loginUser(t, "user2")
   286  	req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
   287  		"_csrf":    GetCSRF(t, session, "/user/settings"),
   288  		"name":     "user2",
   289  		"email":    "user@example.com",
   290  		"language": "en-US",
   291  		"location": "A/b",
   292  	})
   293  	session.MakeRequest(t, req, http.StatusSeeOther)
   294  
   295  	req = NewRequest(t, "GET", "/user2/")
   296  	resp := session.MakeRequest(t, req, http.StatusOK)
   297  	htmlDoc := NewHTMLParser(t, resp.Body)
   298  	htmlDoc.AssertElement(t, `a[href="https://example/foo/A%2Fb"]`, true)
   299  }