|
6 | 6 | package auth
|
7 | 7 |
|
8 | 8 | import (
|
| 9 | + "fmt" |
9 | 10 | "net/http"
|
10 | 11 | "strings"
|
11 | 12 |
|
| 13 | + "code.gitea.io/gitea/models/db" |
12 | 14 | user_model "code.gitea.io/gitea/models/user"
|
13 | 15 | "code.gitea.io/gitea/modules/log"
|
14 | 16 | "code.gitea.io/gitea/modules/setting"
|
@@ -55,32 +57,74 @@ func (r *ReverseProxy) Name() string {
|
55 | 57 | // the revese proxy.
|
56 | 58 | // If a username is available in the "setting.ReverseProxyAuthUser" header an existing
|
57 | 59 | // user object is returned (populated with username or email found in header).
|
58 |
| -// Returns nil if header is empty. |
| 60 | +// Returns nil if header is empty or internal API is being called. |
59 | 61 | func (r *ReverseProxy) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) *user_model.User {
|
| 62 | + |
| 63 | + // Internal API should not use this auth method. |
| 64 | + if middleware.IsInternalPath(req) { |
| 65 | + return nil |
| 66 | + } |
| 67 | + |
| 68 | + // Just return user if session is estabilshed already. |
| 69 | + user := SessionUser(sess) |
| 70 | + if user != nil { |
| 71 | + return user |
| 72 | + } |
| 73 | + |
60 | 74 | username := r.getUserName(req)
|
61 | 75 | if len(username) == 0 {
|
62 | 76 | return nil
|
63 | 77 | }
|
64 | 78 | log.Trace("ReverseProxy Authorization: Found username: %s", username)
|
65 | 79 |
|
66 |
| - user, err := user_model.GetUserByName(username) |
67 |
| - if err != nil { |
68 |
| - if !user_model.IsErrUserNotExist(err) || !r.isAutoRegisterAllowed() { |
69 |
| - log.Error("GetUserByName: %v", err) |
| 80 | + var err error |
| 81 | + |
| 82 | + if r.isAutoRegisterAllowed() { |
| 83 | + // Use auto registration from reverse proxy if ENABLE_REVERSE_PROXY_AUTO_REGISTRATION enabled. |
| 84 | + if user, err = user_model.GetUserByName(username); err != nil { |
| 85 | + if user_model.IsErrUserNotExist(err) && r.isAutoRegisterAllowed() { |
| 86 | + if user = r.newUser(req); user == nil { |
| 87 | + return nil |
| 88 | + } |
| 89 | + } else { |
| 90 | + log.Error("GetUserByName: %v", err) |
| 91 | + return nil |
| 92 | + } |
| 93 | + } |
| 94 | + } else { |
| 95 | + // Use auto registration from other backends if ENABLE_REVERSE_PROXY_AUTO_REGISTRATION not enabled. |
| 96 | + if user, _, err = UserSignIn(username, ""); err != nil { |
| 97 | + if !user_model.IsErrUserNotExist(err) { |
| 98 | + log.Error("UserSignIn: %v", err) |
| 99 | + } |
70 | 100 | return nil
|
71 | 101 | }
|
72 |
| - user = r.newUser(req) |
73 | 102 | }
|
74 | 103 |
|
75 | 104 | // Make sure requests to API paths, attachment downloads, git and LFS do not create a new session
|
76 | 105 | if !middleware.IsAPIPath(req) && !isAttachmentDownload(req) && !isGitRawReleaseOrLFSPath(req) {
|
77 | 106 | if sess != nil && (sess.Get("uid") == nil || sess.Get("uid").(int64) != user.ID) {
|
| 107 | + |
| 108 | + // Register last login. |
| 109 | + user.SetLastLogin() |
| 110 | + |
| 111 | + if err = user_model.UpdateUserCols(db.DefaultContext, user, "last_login_unix"); err != nil { |
| 112 | + log.Error(fmt.Sprintf("ReverseProxy Authorization: error updating user last login time [user: %d]", user.ID)) |
| 113 | + } |
| 114 | + |
| 115 | + // Initialize new session. Will set lang and CSRF cookies. |
78 | 116 | handleSignIn(w, req, sess, user)
|
| 117 | + |
| 118 | + log.Trace("ReverseProxy Authorization: Logged in user %-v", user) |
79 | 119 | }
|
| 120 | + |
| 121 | + // Unfortunatelly we cannot do redirect here (would break git HTTP requests) to |
| 122 | + // reload page with user locale so first page after login may be displayed in |
| 123 | + // wrong language. Language handling in SSO mode should be reconsidered |
| 124 | + // in future gitea versions. |
80 | 125 | }
|
81 |
| - store.GetData()["IsReverseProxy"] = true |
82 | 126 |
|
83 |
| - log.Trace("ReverseProxy Authorization: Logged in user %-v", user) |
| 127 | + store.GetData()["IsReverseProxy"] = true |
84 | 128 | return user
|
85 | 129 | }
|
86 | 130 |
|
|
0 commit comments