func newRestServerAPI(datasource *datasource.DataSource) *restServerAPI { rest := grest.NewApi() rest.Use(grest.DefaultDevStack...) rest.Use(&grest.CorsMiddleware{ RejectNonCorsRequests: false, OriginValidator: func(origin string, request *grest.Request) bool { // TODO Origin check return true }, AllowedMethods: []string{"GET", "POST", "PUT", "PATCH", "DELETE"}, AllowedHeaders: []string{ "Accept", "Content-Type", "X-Custom-Header", "Origin", "Authorization"}, AccessControlAllowCredentials: true, AccessControlMaxAge: 3600, }) var bearerAuthMiddleware = &AuthBearerMiddleware{ Realm: "RestAuthentication", Authenticator: func(token string) string { parsedToken, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) { if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) } return datasource.ConfigByteArray("TOKEN_SIGN_KEY"), nil }) if err == nil && parsedToken.Valid { return parsedToken.Claims["email"].(string) } else { return "" } }, Authorizer: func(request *grest.Request, userID string) bool { user, err := datasource.UserByEmail(userID) if err != nil { logging.Log(debugTag, "Couldn't fetch user for userID=%s", userID) return false } request.Env["REMOTE_USER_OBJECT"] = user return true }, } rest.Use(&grest.IfMiddleware{ Condition: func(request *grest.Request) bool { return request.URL.Path != "/login" }, IfTrue: bearerAuthMiddleware, }) return &restServerAPI{ rest: rest, ds: datasource, } }
func procMsg(msg ClientMessage, datasource *datasource.DataSource) { rcpt := make([]string, 0, 100) toHost := strings.Split(msg.To, "@")[1] if isAllowedHost(toHost) { user, err := datasource.UserByEmail(msg.To) if err == nil { rcpt = append(rcpt, user.InboxAddr) } else { group, err := datasource.GroupByEmail(msg.To) if err == nil { for _, member := range group.Members { user, err = datasource.UserByEmail(member) if err == nil { rcpt = append(rcpt, user.InboxAddr) } } } else { logln(1, "Can't find such user or group") return } } } logln(1, fmt.Sprintf("%s", msg.From)) fromHost := strings.Split(msg.From, "@")[1] if isAllowedHost(fromHost) { if msg.Auth == false || msg.Username != msg.From { logln(1, fmt.Sprintf("%s %s", msg.Username, msg.From)) logln(1, "Not authenticated") return } } for _, email := range rcpt { logln(1, email) host := strings.Split(email, "@")[1] nss, err := net.LookupMX(host) if err == nil { for _, ns := range nss { logln(1, fmt.Sprintf("%s %d", ns.Host, ns.Pref)) } curMsg := msg curMsg.To = email sendMsg(nss[0], curMsg) } else { logln(1, "Error in lookup MX") } } }
func clientAuth(client *Client, datasource *datasource.DataSource) string { succ := "235 Authentication succeeded" fail := "535 Authentication failed" user, err := datasource.UserByEmail(client.username) if err != nil { return fail } logln(1, user.Email) if user.AcceptsPassword(client.password, datasource.ConfigByteArray("PASSWORD_SALT")) { client.auth = true return succ } return fail }