@@ -7,19 +7,17 @@ package sso
7
7
import (
8
8
"errors"
9
9
"net/http"
10
- "reflect"
11
10
"strings"
12
11
13
12
"code.gitea.io/gitea/models"
14
13
"code.gitea.io/gitea/modules/base"
15
14
"code.gitea.io/gitea/modules/log"
16
15
"code.gitea.io/gitea/modules/setting"
17
-
18
- "gitea.com/macaron/macaron"
19
- "gitea.com/macaron/session"
16
+ "code.gitea.io/gitea/modules/templates"
20
17
21
18
gouuid "github.com/google/uuid"
22
19
"github.com/quasoft/websspi"
20
+ "github.com/unrolled/render"
23
21
)
24
22
25
23
const (
@@ -41,14 +39,26 @@ var (
41
39
// On successful authentication returns a valid user object.
42
40
// Returns nil if authentication fails.
43
41
type SSPI struct {
42
+ rnd * render.Render
44
43
}
45
44
46
45
// Init creates a new global websspi.Authenticator object
47
46
func (s * SSPI ) Init () error {
48
47
config := websspi .NewConfig ()
49
48
var err error
50
49
sspiAuth , err = websspi .New (config )
51
- return err
50
+ if err != nil {
51
+ return err
52
+ }
53
+ s .rnd = render .New (render.Options {
54
+ Extensions : []string {".tmpl" },
55
+ Directory : "templates" ,
56
+ Funcs : templates .NewFuncMap (),
57
+ Asset : templates .GetAsset ,
58
+ AssetNames : templates .GetAssetNames ,
59
+ IsDevelopment : setting .RunMode != "prod" ,
60
+ })
61
+ return nil
52
62
}
53
63
54
64
// Free releases resources used by the global websspi.Authenticator object
@@ -65,8 +75,8 @@ func (s *SSPI) IsEnabled() bool {
65
75
// If authentication is successful, returs the corresponding user object.
66
76
// If negotiation should continue or authentication fails, immediately returns a 401 HTTP
67
77
// response code, as required by the SPNEGO protocol.
68
- func (s * SSPI ) VerifyAuthData (req * http.Request , store DataStore , sess SessionStore ) * models.User {
69
- if ! s .shouldAuthenticate (ctx ) {
78
+ func (s * SSPI ) VerifyAuthData (req * http.Request , w http. ResponseWriter , store DataStore , sess SessionStore ) * models.User {
79
+ if ! s .shouldAuthenticate (req ) {
70
80
return nil
71
81
}
72
82
@@ -76,22 +86,29 @@ func (s *SSPI) VerifyAuthData(req *http.Request, store DataStore, sess SessionSt
76
86
return nil
77
87
}
78
88
79
- userInfo , outToken , err := sspiAuth .Authenticate (req , ctx . Resp )
89
+ userInfo , outToken , err := sspiAuth .Authenticate (req , w )
80
90
if err != nil {
81
91
log .Warn ("Authentication failed with error: %v\n " , err )
82
- sspiAuth .AppendAuthenticateHeader (ctx . Resp , outToken )
92
+ sspiAuth .AppendAuthenticateHeader (w , outToken )
83
93
84
94
// Include the user login page in the 401 response to allow the user
85
95
// to login with another authentication method if SSPI authentication
86
96
// fails
87
- addFlashErr (ctx , ctx .Tr ("auth.sspi_auth_failed" ))
88
- ctx .Data ["EnableOpenIDSignIn" ] = setting .Service .EnableOpenIDSignIn
89
- ctx .Data ["EnableSSPI" ] = true
90
- ctx .HTML (401 , string (tplSignIn ))
97
+ store .GetData ()["Flash" ] = map [string ]string {
98
+ "ErrMsg" : err .Error (),
99
+ }
100
+ store .GetData ()["EnableOpenIDSignIn" ] = setting .Service .EnableOpenIDSignIn
101
+ store .GetData ()["EnableSSPI" ] = true
102
+
103
+ err := s .rnd .HTML (w , 401 , string (tplSignIn ), templates .BaseVars ().Merge (store .GetData ()))
104
+ if err != nil {
105
+ log .Error ("%v" , err )
106
+ }
107
+
91
108
return nil
92
109
}
93
110
if outToken != "" {
94
- sspiAuth .AppendAuthenticateHeader (ctx . Resp , outToken )
111
+ sspiAuth .AppendAuthenticateHeader (w , outToken )
95
112
}
96
113
97
114
username := sanitizeUsername (userInfo .Username , cfg )
@@ -110,16 +127,16 @@ func (s *SSPI) VerifyAuthData(req *http.Request, store DataStore, sess SessionSt
110
127
log .Error ("User '%s' not found" , username )
111
128
return nil
112
129
}
113
- user , err = s .newUser (ctx , username , cfg )
130
+ user , err = s .newUser (username , cfg )
114
131
if err != nil {
115
132
log .Error ("CreateUser: %v" , err )
116
133
return nil
117
134
}
118
135
}
119
136
120
137
// Make sure requests to API paths and PWA resources do not create a new session
121
- if ! isAPIPath (ctx ) && ! isAttachmentDownload (ctx ) {
122
- handleSignIn (ctx , sess , user )
138
+ if ! isAPIPath (req ) && ! isAttachmentDownload (req ) {
139
+ handleSignIn (w , req , sess , user )
123
140
}
124
141
125
142
return user
@@ -146,7 +163,7 @@ func (s *SSPI) shouldAuthenticate(req *http.Request) (shouldAuth bool) {
146
163
if path == "/user/login" {
147
164
if req .FormValue ("user_name" ) != "" && req .FormValue ("password" ) != "" {
148
165
shouldAuth = false
149
- } else if ctx . Req .FormValue ("auth_with_sspi" ) == "1" {
166
+ } else if req .FormValue ("auth_with_sspi" ) == "1" {
150
167
shouldAuth = true
151
168
}
152
169
} else if isInternalPath (req ) {
@@ -217,20 +234,6 @@ func sanitizeUsername(username string, cfg *models.SSPIConfig) string {
217
234
return username
218
235
}
219
236
220
- // addFlashErr adds an error message to the Flash object mapped to a macaron.Context
221
- func addFlashErr (ctx * macaron.Context , err string ) {
222
- fv := ctx .GetVal (reflect .TypeOf (& session.Flash {}))
223
- if ! fv .IsValid () {
224
- return
225
- }
226
- flash , ok := fv .Interface ().(* session.Flash )
227
- if ! ok {
228
- return
229
- }
230
- flash .Error (err )
231
- ctx .Data ["Flash" ] = flash
232
- }
233
-
234
237
// init registers the SSPI auth method as the last method in the list.
235
238
// The SSPI plugin is expected to be executed last, as it returns 401 status code if negotiation
236
239
// fails (or if negotiation should continue), which would prevent other authentication methods
0 commit comments