MCPcopy
hub / github.com/PatchMon/PatchMon / Login

Method Login

server-source-code/internal/handler/auth.go:145–318  ·  view source on GitHub ↗

Login handles POST /auth/login.

(w http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

143
144// Login handles POST /auth/login.
145func (h *AuthHandler) Login(w http.ResponseWriter, r *http.Request) {
146 if h.log != nil {
147 h.log.Debug("auth request", "method", r.Method, "path", r.URL.Path)
148 }
149 if h.cfg.OidcEnabled && h.cfg.OidcDisableLocalAuth {
150 Error(w, http.StatusForbidden, "Local authentication is disabled. Please use SSO.")
151 return
152 }
153 var req LoginRequest
154 if err := decodeJSON(r, &req); err != nil {
155 if h.log != nil {
156 h.log.Debug("auth login invalid body", "error", err)
157 }
158 Error(w, http.StatusBadRequest, "Invalid request body")
159 return
160 }
161 if req.Username == "" || req.Password == "" {
162 Error(w, http.StatusBadRequest, "username and password required")
163 return
164 }
165 if h.log != nil {
166 h.log.Debug("auth login attempt", "username", req.Username)
167 }
168
169 // Login lockout: check before password verification
170 if h.loginLockout != nil {
171 identifier := h.loginLockout.Identifier(h.clientIP(r), req.Username)
172 if locked, remainingSec := h.loginLockout.IsLocked(r.Context(), identifier); locked {
173 w.Header().Set("Retry-After", strconv.Itoa(remainingSec))
174 JSON(w, http.StatusTooManyRequests, map[string]interface{}{
175 "message": "Too many failed login attempts. Try again later.",
176 "remaining_seconds": remainingSec,
177 })
178 return
179 }
180 }
181
182 user, err := h.users.GetByUsernameOrEmail(r.Context(), req.Username)
183 if err != nil {
184 if h.log != nil {
185 h.log.Debug("auth login user not found", "identifier", req.Username, "err", err.Error())
186 }
187 Error(w, http.StatusUnauthorized, "Invalid credentials")
188 return
189 }
190 if h.log != nil {
191 h.log.Debug("auth login user found", "user_id", user.ID, "username", user.Username, "is_active", user.IsActive, "has_password", user.PasswordHash != nil)
192 }
193 if !user.IsActive {
194 if h.log != nil {
195 h.log.Debug("auth login account disabled", "user_id", user.ID)
196 }
197 Error(w, http.StatusUnauthorized, "Account is disabled")
198 return
199 }
200 if user.PasswordHash == nil {
201 if h.log != nil {
202 h.log.Debug("auth login no password hash", "user_id", user.ID, "reason", "oidc_only_or_missing")

Callers

nothing calls this directly

Calls 15

clientIPMethod · 0.95
hasValidDeviceTrustMethod · 0.95
completeLoginMethod · 0.95
ErrorFunction · 0.85
decodeJSONFunction · 0.85
IdentifierMethod · 0.80
IsLockedMethod · 0.80
GetByUsernameOrEmailMethod · 0.80
ErrorMethod · 0.80
EmitEventMethod · 0.80
TouchLastUsedMethod · 0.80
JSONFunction · 0.70

Tested by

no test coverage detected