This repository has been archived by the owner on Mar 11, 2021. It is now read-only.
/
search.go
129 lines (108 loc) · 3.73 KB
/
search.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package controller
import (
"regexp"
"github.com/fabric8-services/fabric8-auth/app"
"github.com/fabric8-services/fabric8-auth/application"
account "github.com/fabric8-services/fabric8-auth/authentication/account/repository"
"github.com/fabric8-services/fabric8-auth/errors"
"github.com/fabric8-services/fabric8-auth/jsonapi"
"github.com/fabric8-services/fabric8-auth/log"
"github.com/fabric8-services/fabric8-auth/application/transaction"
"github.com/goadesign/goa"
)
type searchConfiguration interface {
GetHTTPAddress() string
GetMaxUsersListLimit() int
}
// SearchController implements the search resource.
type SearchController struct {
*goa.Controller
app application.Application
configuration searchConfiguration
}
// NewSearchController creates a search controller.
func NewSearchController(service *goa.Service, app application.Application, configuration searchConfiguration) *SearchController {
return &SearchController{Controller: service.NewController("SearchController"), app: app, configuration: configuration}
}
// Users runs the user search action.
func (c *SearchController) Users(ctx *app.UsersSearchContext) error {
_, err := c.app.UserService().LoadContextIdentityIfNotBanned(ctx)
if err != nil {
return jsonapi.JSONErrorResponse(ctx, errors.NewUnauthorizedError(err.Error()))
}
q := ctx.Q
if len(q) == 0 {
return jsonapi.JSONErrorResponse(ctx, errors.NewBadParameterError("", "search query should be longer"))
}
var result []account.Identity
var count int
exceeded := false
offset, limit := computePagingLimits(ctx.PageOffset, ctx.PageLimit)
r, err := regexp.Compile(`\w`) // check for A-Z a-z 0-9
searchLimit := limit
// Don't return more users than allowed by configuration
if offset >= c.configuration.GetMaxUsersListLimit() {
exceeded = true
} else if offset+limit > c.configuration.GetMaxUsersListLimit() {
searchLimit = c.configuration.GetMaxUsersListLimit() - offset
}
if r.MatchString(q) && len(q) > 1 { // 2 or more characters
err = transaction.Transactional(c.app, func(tr transaction.TransactionalResources) error {
result, count, err = tr.Identities().Search(ctx, q, offset, searchLimit)
return err
})
if err != nil {
log.Error(ctx, map[string]interface{}{
"err": err,
}, "unable to run search query on users.")
return jsonapi.JSONErrorResponse(ctx, err)
}
}
if exceeded {
result = []account.Identity{}
}
if count > c.configuration.GetMaxUsersListLimit() {
// Hide the real count if it's more than the max allowed limit
count = c.configuration.GetMaxUsersListLimit()
}
var users []*app.UserData
for i := range result {
ident := result[i]
id := ident.ID.String()
userID := ident.User.ID.String()
email := ident.User.Email
if ident.User.EmailPrivate {
email = ""
}
users = append(users, &app.UserData{
Type: "identities",
ID: &id,
Attributes: &app.UserDataAttributes{
CreatedAt: &ident.User.CreatedAt,
UpdatedAt: &ident.User.UpdatedAt,
Username: &ident.Username,
FullName: &ident.User.FullName,
ImageURL: &ident.User.ImageURL,
Bio: &ident.User.Bio,
URL: &ident.User.URL,
UserID: &userID,
IdentityID: &id,
Email: &email,
EmailPrivate: &ident.User.EmailPrivate,
Company: &ident.User.Company,
},
})
}
// If there are no search results ensure that the 'data' section of the jsonapi
// response is not null, rather [] (empty array)
if users == nil {
users = []*app.UserData{}
}
response := app.UserList{
Data: users,
Links: &app.PagingLinks{},
Meta: &app.UserListMeta{TotalCount: count},
}
setPagingLinks(response.Links, buildAbsoluteURL(ctx.RequestData), len(result), offset, limit, count, "q="+q)
return ctx.OK(&response)
}