diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..09f1553 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,44 @@ +version: "3" +services: + gamma-db: + image: postgres:10 + environment: + POSTGRES_USER: user + POSTGRES_DB: postgres + POSTGRES_PASSWORD: password + + gamma-frontend: + image: cthit/gamma-frontend:development + network_mode: host + ports: + - 3000:3000 + + gamma-backend: + image: cthit/gamma-backend:latest + environment: + # Default admin user name = admin + # Default admin password = password + + DB_USER: user + DB_PASSWORD: password + DB_HOST: gamma-db + DB_PORT: 5432 + DB_NAME: postgres + + REDIS_HOST: redis + REDIS_PASSWORD: "" + + SERVER_PORT: 8081 + FRONTEND_REDIRECT_URI: http://localhost:3000/login + SUCCESSFUL_LOGIN: http://localhost:3000 + CORS_ALLOWED_ORIGIN: http://localhost:3000 + COOKIE_DOMAIN: localhost + PRODUCTION: "false" + IS_MOCKING_CLIENT: "true" + DEFAULT_REDIRECT_URI: http://localhost:3001/callback + + ports: + - 8081:8081 + + redis: + image: redis:5.0 diff --git a/example.config.toml b/example.config.toml index 8212381..cd60cf4 100644 --- a/example.config.toml +++ b/example.config.toml @@ -6,6 +6,10 @@ servicekeyfile = "gapps.json" adminaccount = "admin@mydomain.ex" +[gamma.producer] + apiKey = "key" + url = "http://localhost:8080" + [ldap] url = "ldap.mydomain.ex:636" servername = "mydomain.ex" diff --git a/internal/app/cli/bgc.go b/internal/app/cli/bgc.go index b06d937..2bf563f 100644 --- a/internal/app/cli/bgc.go +++ b/internal/app/cli/bgc.go @@ -2,11 +2,17 @@ package cli import ( "fmt" + "github.com/cthit/goldapps/internal/pkg/actions" "github.com/cthit/goldapps/internal/pkg/duplicates" "github.com/cthit/goldapps/internal/pkg/model" ) +const ( + colorRed = "\033[31m" + colorGreen = "\033[32m" +) + func init() { loadFlags() @@ -109,6 +115,52 @@ func Run() { } } +func has(member string, members []string) bool { + for _, v := range members { + if model.CompareEmails(v, member) { + return true + } + } + return false +} + +func printGroupDiff(before model.Group, after model.Group) { + fmt.Printf("\tUpdate: ") + if before.Email != after.Email { + fmt.Printf("\t%s -> %s\n", before.Email, after.Email) + } else { + fmt.Printf("\t\t%s\n", after.Email) + } + if before.Type != after.Email { + fmt.Printf("\t\t\t%s -> %s\n", before.Type, after.Type) + } + + added := []string{} + deleted := []string{} + + for _, member := range before.Members { + if !has(member, after.Members) { + deleted = append(deleted, member) + } + } + + for _, member := range after.Members { + if !has(member, before.Members) { + added = append(added, member) + } + } + + for _, del := range deleted { + fmt.Printf("\t\t\t- %s\n", del) + } + + for _, add := range added { + fmt.Printf("\t\t\t+ %s\n", add) + } + + fmt.Printf("\t\t\tAliases: %v -> %v\n", before.Aliases, after.Aliases) +} + func getGroupChanges(proposedChanges actions.GroupActions) actions.GroupActions { if !flags.interactive && flags.noInteraction { fmt.Printf( @@ -137,11 +189,7 @@ func getGroupChanges(proposedChanges actions.GroupActions) actions.GroupActions fmt.Printf("(Groups) Changes (%d):\n", len(proposedChanges.Updates)) if len(proposedChanges.Updates) > 0 { for _, update := range proposedChanges.Updates { - fmt.Printf("\tUpdate:\n") - fmt.Printf("\t\tFrom:\n") - fmt.Printf("\t\t\t%v\n", update.Before) - fmt.Printf("\t\tTo:\n") - fmt.Printf("\t\t\t%v\n", update.After) + printGroupDiff(update.Before, update.After) } add := askBool( fmt.Sprintf("(Groups) Do you want to commit those %d updates?", len(proposedChanges.Updates)), diff --git a/internal/app/cli/services.go b/internal/app/cli/services.go index 5f5a14f..cf83755 100644 --- a/internal/app/cli/services.go +++ b/internal/app/cli/services.go @@ -2,13 +2,15 @@ package cli import ( "fmt" + "regexp" + "github.com/cthit/goldapps/internal/pkg/model" "github.com/cthit/goldapps/internal/pkg/services" "github.com/cthit/goldapps/internal/pkg/services/admin" + "github.com/cthit/goldapps/internal/pkg/services/gamma" "github.com/cthit/goldapps/internal/pkg/services/json" "github.com/cthit/goldapps/internal/pkg/services/ldap" "github.com/spf13/viper" - "regexp" ) func getConsumer() services.UpdateService { @@ -49,7 +51,7 @@ func getConsumer() services.UpdateService { func getProvider() services.CollectionService { var from string if flags.interactive { - from = askString("which providers would you like to use, 'ldap', 'gapps' or '*.json'?", "ldap") + from = askString("which providers would you like to use, 'ldap', 'gapps', 'gamma' or '*.json'?", "ldap") } else { from = flags.from } @@ -69,6 +71,16 @@ func getProvider() services.CollectionService { panic(err) } return provider + case "gamma": + provider, err := gamma.CreateGammaService( + viper.GetString("gamma.provider.apiKey"), + viper.GetString("gamma.provider.url")) + if err != nil { + fmt.Println("Failed to connect to Gamma") + panic(err) + } + return provider + default: isJson, _ := regexp.MatchString(`.+\.json$`, from) if isJson { diff --git a/internal/pkg/services/gamma/gammaRequests.go b/internal/pkg/services/gamma/gammaRequests.go new file mode 100644 index 0000000..3d0f0a2 --- /dev/null +++ b/internal/pkg/services/gamma/gammaRequests.go @@ -0,0 +1,96 @@ +package gamma + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "log" + "net/http" +) + +//Executes a generic get request to Gamma +func gammaReq(s *GammaService, endpoint string, response interface{}) error { + req, err := http.NewRequest("GET", fmt.Sprintf("%s%s", s.gammaUrl, endpoint), nil) + if err != nil { + log.Println(err) + return err + } + + req.Header.Set("Authorization", fmt.Sprintf("pre-shared %s", s.apiKey)) + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + log.Println(err) + return err + } + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + log.Println(err) + return err + } + + err = json.Unmarshal(body, &response) + if err != nil { + log.Println(err) + return err + } + + return nil +} + +//Fetches all the fkit-groups from Gamma +func getGammaGroups(s *GammaService) ([]FKITGroup, error) { + var groups struct { + Groups []FKITGroup `json:"groups"` + } + + err := gammaReq(s, "/api/groups", &groups) + if err != nil { + log.Println(err) + return nil, err + } + + return groups.Groups, nil +} + +//Fetches all super groups from Gamma +func getSuperGroups(s *GammaService) ([]FKITSuperGroup, error) { + var superGroups []FKITSuperGroup + + err := gammaReq(s, "/api/superGroups", &superGroups) + if err != nil { + log.Println(err) + return nil, err + } + + return superGroups, nil +} + +//Fetches all posts which has a mail prefix +func getMailPosts(s *GammaService) ([]Post, error) { + posts := []Post{} + err := gammaReq(s, "/api/groups/posts", &posts) + if err != nil { + return nil, err + } + + mailPosts := []Post{} + for _, post := range posts { + if post.EmailPrefix != "" { + mailPosts = append(mailPosts, post) + } + } + + return mailPosts, nil +} + +//Fetches all active groups +func getActiveGroups(s *GammaService) ([]FKITGroup, error) { + groups := struct { + GetFKITGroupResponse []FKITGroup `json:"getFKITGroupResponse"` + }{} + err := gammaReq(s, "/api/groups/active", &groups) + return groups.GetFKITGroupResponse, err +} diff --git a/internal/pkg/services/gamma/lists.go b/internal/pkg/services/gamma/lists.go new file mode 100644 index 0000000..ebdbab4 --- /dev/null +++ b/internal/pkg/services/gamma/lists.go @@ -0,0 +1,211 @@ +package gamma + +import ( + "fmt" + + "github.com/cthit/goldapps/internal/pkg/model" +) + +//Both SuperGroupList and NormalGroupList follows a linked list structure + +type SuperGroupList struct { + SuperGroupId string + Next *SuperGroupList + MemberGroups *NormalGroupList + Kit bool + model.Group +} + +type NormalGroupList struct { + GroupId string + Next *NormalGroupList + Active bool + model.Group +} + +type PostGroupList struct { + Next *PostGroupList + GroupName string + EmailPrefix string + Kit bool + model.Group +} + +func (li *NormalGroupList) insert(group *FKITGroup) *NormalGroupList { + //If you have reached the last item of the chain + //create a new item connected to a group + if li.Next == nil { + return li.newListItem(group) + } + + //If you have reached the correct group + //append the member emails + if group.ID == li.GroupId { + li.Members = append(li.Members, getMembers(group)...) + return li + } + + li.Next = li.Next.insert(group) + return li +} + +//Creates a group item which contains the group email, members and a pointer to the next item +func (next *NormalGroupList) newListItem(group *FKITGroup) *NormalGroupList { + return &NormalGroupList{ + GroupId: group.ID, + Next: next, + Active: group.Active || group.SuperGroup.Type == "ALUMNI", + Group: model.Group{ + Email: group.Email, + Type: group.SuperGroup.Type, + Members: getMembers(group), + Aliases: nil, + Expendable: false, + }, + } +} + +//Returns all active and inactive groups in the list +func (li *NormalGroupList) toGroups() ([]model.Group, []model.Group) { + if li.Next == nil { + return []model.Group{}, []model.Group{} + } + + active, inactive := li.Next.toGroups() + + if len(li.Members) <= 0 { + return active, inactive + } + + if li.Active { + return append(active, li.Group), inactive + } + + return active, append(inactive, li.Group) +} + +func (li *SuperGroupList) insert(group *FKITGroup) *SuperGroupList { + //Ignoring admin group + if group.SuperGroup.Type == "ADMIN" { + return li + } + + //If you have reached the last item of the chain + //create a new item connected to a super group + if li.Next == nil { + return li.newListItem(group) + } + + //If you have reached the correct super group + //save the normal group as a group member + if group.SuperGroup.Email == li.Email { + li.MemberGroups = li.MemberGroups.insert(group) + return li + } + + li.Next = li.Next.insert(group) + return li +} + +//Creates a super group item which contains the group email, members and a pointer to the next item +func (next *SuperGroupList) newListItem(group *FKITGroup) *SuperGroupList { + memberGroups := &NormalGroupList{} + return &SuperGroupList{ + SuperGroupId: group.SuperGroup.ID, + Next: next, + MemberGroups: memberGroups.insert(group), + Kit: isKit(group), + Group: model.Group{ + Email: group.SuperGroup.Email, + Type: group.SuperGroup.Type, + Members: []string{}, + Aliases: nil, + Expendable: false, + }, + } +} + +//Returns the fkit group and all the rest of the groups +func (li *SuperGroupList) toGroups() (model.Group, model.Group, []model.Group) { + if li.Next == nil { + return emptyGroup("grupper"), emptyGroup("kommitteer"), []model.Group{} + } + + activeGroups, inactiveGroups := li.MemberGroups.toGroups() + superGroup := li.Group + + for _, group := range activeGroups { + superGroup.Members = append(superGroup.Members, group.Email) + } + + if len(superGroup.Members) <= 0 { + superGroup.Members = []string{"ita.styrit@chalmers.it"} + } + + fkit, kit, groups := li.Next.toGroups() + groups = append(groups, inactiveGroups...) + groups = append(groups, activeGroups...) + + if li.Kit { + kit.Members = append(kit.Members, li.Email) + } + + if li.Type != "ALUMNI" { + fkit.Members = append(fkit.Members, li.Email) + } + + return fkit, kit, append(groups, superGroup) +} + +//Creates a new post mail group +func (pl *PostGroupList) newListItem(group *FKITGroup, member *FKITUser) *PostGroupList { + return &PostGroupList{ + Next: pl, + EmailPrefix: member.Post.EmailPrefix, + GroupName: group.SuperGroup.Name, + Kit: isKit(group), + Group: model.Group{ + Email: fmt.Sprintf("%s.%s", member.Post.EmailPrefix, group.SuperGroup.Email), + Members: []string{getMemberEmail(group, member)}, + Aliases: nil, + Expendable: false, + }, + } +} + +//Creates a post email for active member if their posts should have email +func (pl *PostGroupList) insert(group *FKITGroup, member *FKITUser) *PostGroupList { + if !group.Active || member.Post.EmailPrefix == "" || (!member.Gdpr && isKit(group)) { + return pl + } + + if pl.Next == nil { + return pl.newListItem(group, member) + } + + if pl.GroupName == group.SuperGroup.Name && + pl.EmailPrefix == member.Post.EmailPrefix { + pl.Members = append(pl.Members, getMemberEmail(group, member)) + return pl + } + + pl.Next = pl.Next.insert(group, member) + return pl +} + +//Returns all post groups in kit and post groups which is not in kit +func (pl *PostGroupList) toGroups() ([]model.Group, []model.Group) { + if pl.Next == nil { + return []model.Group{}, []model.Group{} + } + + kit, other := pl.Next.toGroups() + + if pl.Kit { + kit = append(kit, pl.Group) + } else { + other = append(other, pl.Group) + } + + return kit, other +} diff --git a/internal/pkg/services/gamma/service.go b/internal/pkg/services/gamma/service.go new file mode 100644 index 0000000..a7f3320 --- /dev/null +++ b/internal/pkg/services/gamma/service.go @@ -0,0 +1,160 @@ +package gamma + +import ( + "fmt" + "log" + "strings" + + "github.com/cthit/goldapps/internal/pkg/model" +) + +type GammaService struct { + apiKey string + gammaUrl string +} + +//Creates a gamma service which has the url to gamma and the pre-shared key +func CreateGammaService(apiKey string, url string) (GammaService, error) { + return GammaService{ + apiKey: apiKey, + gammaUrl: url, + }, nil +} + +//Determins if the specified user in the specified group should have a gsuit account +func shouldHaveMail(group *FKITGroup, member *FKITUser) bool { + return isKit(group) && member.Gdpr && group.Active +} + +//Determins if specified group is a member of KIT +func isKit(group *FKITGroup) bool { + return (group.SuperGroup.Type == "COMMITTEE" || group.SuperGroup.Type == "BOARD" || group.SuperGroup.Type == "FUNCTIONARIES") +} + +//Returns the email which should be used for a specific user +func getMemberEmail(group *FKITGroup, member *FKITUser) string { + if shouldHaveMail(group, member) { + return fmt.Sprintf("%s@chalmers.it", member.Cid) + } + + return member.Email +} + +//Returns all the Email addresses from the member of a group +func getMembers(group *FKITGroup) []string { + members := make(map[string]bool, len(group.GroupMembers)) + + if !isKit(group) || !group.Active { + for _, member := range group.GroupMembers { + members[getMemberEmail(group, &member)] = true + } + } else { + for _, member := range group.GroupMembers { + if shouldHaveMail(group, &member) { + members[getMemberEmail(group, &member)] = true + } + } + } + + membersMail := []string{} + for mail := range members { + membersMail = append(membersMail, mail) + } + return membersMail +} + +//Creates an empty group with a specific email +func emptyGroup(emailPrefix string) model.Group { + return model.Group{ + Email: fmt.Sprintf("%s@chalmers.it", emailPrefix), + Type: "", + Members: []string{}, + Aliases: nil, + Expendable: false, + } +} + +//Makes a group which contains all the emails of groups with a specified prefix +func groupOfGroups(mailPrefix string, requiredPrefix string, groups []model.Group) model.Group { + newGroup := emptyGroup(mailPrefix) + for _, group := range groups { + if strings.HasPrefix(group.Email, requiredPrefix) { + newGroup.Members = append(newGroup.Members, group.Email) + } + } + + return newGroup +} + +//Creates all mail groups from the fkit groups except post specific groups +func getGroups(fkitGroups []FKITGroup) []model.Group { + groupList := &SuperGroupList{} + for _, group := range fkitGroups { + groupList = groupList.insert(&group) + } + + fkit, kit, groups := groupList.toGroups() + return append(groups, fkit, kit) +} + +//Creates all mail groups connected to posts +func getPostMails(fkitGroups []FKITGroup) []model.Group { + groupList := &PostGroupList{} + for _, group := range fkitGroups { + for _, member := range group.GroupMembers { + groupList = groupList.insert(&group, &member) + } + } + + kit, other := groupList.toGroups() + + ordforanden := groupOfGroups("ordforanden", "ordf", append(kit, other...)) + kitOrdforanden := groupOfGroups("ordforanden.kommitteer", "ordf", kit) + kassorer := groupOfGroups("kassorer", "kassor", append(kit, other...)) + kitKassorer := groupOfGroups("kassorer.kommitteer", "kassor", kit) + + return append(append(kit, ordforanden, kitOrdforanden, kassorer, kitKassorer), other...) +} + +func (s GammaService) GetGroups() ([]model.Group, error) { + groups, err := getGammaGroups(&s) + if err != nil { + log.Println("Failed to fetch all groups from Gamma") + panic(err) + } + activeGroups, err := getActiveGroups(&s) + if err != nil { + log.Println("Failed to fetch active groups") + panic(err) + } + + formattedGroups := getGroups(groups) + formattedGroups = append(formattedGroups, getPostMails(activeGroups)...) + + return formattedGroups, nil +} + +//Fetches all the users in the specified groups +func extractUsers(groups []FKITGroup) []model.User { + userFound := make(map[string]bool) + users := []model.User{} + + for _, group := range groups { + for _, member := range group.GroupMembers { + if shouldHaveMail(&group, &member) && !userFound[member.Cid] { + users = append(users, member.toUser(&group)) + userFound[member.Cid] = true + } + } + } + + return users +} + +func (s GammaService) GetUsers() ([]model.User, error) { + groups, err := getActiveGroups(&s) + if err != nil { + return nil, err + } + return extractUsers(groups), nil +} diff --git a/internal/pkg/services/gamma/service_test.go b/internal/pkg/services/gamma/service_test.go new file mode 100644 index 0000000..8514fe6 --- /dev/null +++ b/internal/pkg/services/gamma/service_test.go @@ -0,0 +1,126 @@ +package gamma + +import ( + "testing" + + "github.com/cthit/goldapps/internal/pkg/model" + "github.com/magiconair/properties/assert" +) + +func TestShouldHaveMail(t *testing.T) { + userA, userB := FKITUser{ + Gdpr: true, + }, FKITUser{ + Gdpr: false, + } + + groupA, groupB, groupC, groupD := FKITGroup{ + SuperGroup: FKITSuperGroup{ + Type: "COMMITTEE", + }, + Active: false, + GroupMembers: []FKITUser{userA, userB}, + }, FKITGroup{ + SuperGroup: FKITSuperGroup{ + Type: "COMMITTEE", + }, + Active: true, + GroupMembers: []FKITUser{userA, userB}, + }, FKITGroup{ + SuperGroup: FKITSuperGroup{ + Type: "BOARD", + }, + Active: false, + GroupMembers: []FKITUser{userA, userB}, + }, FKITGroup{ + SuperGroup: FKITSuperGroup{ + Type: "BOARD", + }, + Active: true, + GroupMembers: []FKITUser{userA, userB}, + } + + assert.Equal(t, shouldHaveMail(&groupA, &userA), false) + assert.Equal(t, shouldHaveMail(&groupA, &userB), false) + assert.Equal(t, shouldHaveMail(&groupB, &userA), true) + assert.Equal(t, shouldHaveMail(&groupB, &userB), false) + assert.Equal(t, shouldHaveMail(&groupC, &userA), false) + assert.Equal(t, shouldHaveMail(&groupC, &userB), false) + assert.Equal(t, shouldHaveMail(&groupD, &userA), true) + assert.Equal(t, shouldHaveMail(&groupD, &userB), false) +} + +func TestGetMembers(t *testing.T) { + userA, userB := FKITUser{ + Cid: "usera", + Email: "usera@gmail.com", + Gdpr: true, + }, FKITUser{ + Cid: "userb", + Email: "userb@gmail.com", + Gdpr: false, + } + + groupA, groupB := FKITGroup{ + SuperGroup: FKITSuperGroup{ + Type: "COMMITTEE", + }, + Active: true, + GroupMembers: []FKITUser{userA, userB}, + }, FKITGroup{ + SuperGroup: FKITSuperGroup{ + Type: "SOCIETY", + }, + Active: true, + GroupMembers: []FKITUser{userA, userB, userB}, + } + + assert.Equal(t, getMembers(&groupA), []string{"usera@chalmers.it"}) + assert.Equal(t, getMembers(&groupB), []string{"usera@gmail.com", "userb@gmail.com"}) +} + +func TestGetGroups(t *testing.T) { + groups := []FKITGroup{ + { + Active: true, + SuperGroup: FKITSuperGroup{ + Type: "COMMITTEE", + Email: "digit@chalmers.it", + }, + }, + } + + want := []model.Group{{"digit@chalmers.it", "COMMITTEE", []string{"ita.styrit@chalmers.it"}, nil, false}, + {"grupper@chalmers.it", "", []string{"digit@chalmers.it"}, nil, false}, + {"kommitteer@chalmers.it", "", []string{"digit@chalmers.it"}, nil, false}} + + assert.Equal(t, getGroups(groups), want) +} + +func TestGetPostMails(t *testing.T) { + userA := FKITUser{ + Cid: "usera", + Post: Post{ + EmailPrefix: "ordf", + }, + Gdpr: true, + Email: "usera@gamil.com", + } + + groupA := FKITGroup{ + Active: true, + SuperGroup: FKITSuperGroup{ + Type: "COMMITTEE", + Name: "supergroup", + }, + GroupMembers: []FKITUser{userA}, + } + + want := []model.Group{{"ordf.supergroup@chalmers.it", "", []string{"usera@chalmers.it"}, nil, false}, + {"ordforanden@chalmers.it", "", []string{"ordf.supergroup@chalmers.it"}, nil, false}, + {"ordforanden.kommitteer@chalmers.it", "", []string{"ordf.supergroup@chalmers.it"}, nil, false}, + {"kassorer@chalmers.it", "", []string{}, nil, false}, + {"kassorer.kommitteer@chalmers.it", "", []string{}, nil, false}} + + assert.Equal(t, want, getPostMails([]FKITGroup{groupA})) +} diff --git a/internal/pkg/services/gamma/structs.go b/internal/pkg/services/gamma/structs.go new file mode 100644 index 0000000..185465f --- /dev/null +++ b/internal/pkg/services/gamma/structs.go @@ -0,0 +1,98 @@ +package gamma + +import ( + "fmt" + "github.com/cthit/goldapps/internal/pkg/model" +) + +type SvEn struct { + Sv string `json:"sv"` + En string `json:"en"` +} + +type FKITSuperGroup struct { + ID string `json:"id"` + Name string `json:"name"` + PrettyName string `json:"prettyName"` + Type string `json:"type"` + Email string `json:"email"` +} + +type Post struct { + ID string `json:"id"` + Sv string `json:"sv"` + En string `json:"en"` + EmailPrefix string `json:"emailPrefix"` +} + +type FKITGroupDTO struct { + ID string `json:"id"` + BecomesActive int64 `json:"becomesActive"` + BecomesInactive int64 `json:"becomesInactive"` + Description SvEn `json:"description"` + Email string `json:"email"` + Function SvEn `json:"function"` + Name string `json:"name"` + PrettyName string `json:"prettyName"` + AvatarURL interface{} `json:"avatarURL"` + SuperGroup FKITSuperGroup `json:"superGroup"` + Active bool `json:"active"` +} + +type FKITUser struct { + Post Post `json:"post"` + FkitGroupDTO FKITGroupDTO `json:"fkitGroupDTO"` + UnofficialPostName string `json:"unofficialPostName"` + ID string `json:"id"` + Cid string `json:"cid"` + Nick string `json:"nick"` + FirstName string `json:"firstName"` + LastName string `json:"lastName"` + Email string `json:"email"` + Phone interface{} `json:"phone"` + Language string `json:"language"` + AvatarURL string `json:"avatarUrl"` + Gdpr bool `json:"gdpr"` + UserAgreement bool `json:"userAgreement"` + AccountLocked bool `json:"accountLocked"` + AcceptanceYear int `json:"acceptanceYear"` + Authorities interface{} `json:"authorities"` + Activated bool `json:"activated"` + Username string `json:"username"` + AccountNonExpired bool `json:"accountNonExpired"` + AccountNonLocked bool `json:"accountNonLocked"` + CredentialsNonExpired bool `json:"credentialsNonExpired"` + Enabled bool `json:"enabled"` +} + +type FKITGroup struct { + ID string `json:"id"` + BecomesActive int64 `json:"becomesActive"` + BecomesInactive int64 `json:"becomesInactive"` + Description SvEn `json:"description"` + Email string `json:"email"` + Function SvEn `json:"function"` + Name string `json:"name"` + PrettyName string `json:"prettyName"` + AvatarURL interface{} `json:"avatarURL"` + SuperGroup FKITSuperGroup `json:"superGroup"` + Active bool `json:"active"` + GroupMembers []FKITUser `json:"groupMembers"` + NoAccountMembers []interface{} `json:"noAccountMembers"` +} + +func (user *FKITUser) toUser(group *FKITGroup) model.User { + newUser := model.User{} + newUser.Cid = user.Cid + newUser.FirstName = user.FirstName + newUser.SecondName = user.LastName + newUser.Nick = user.Nick + + if shouldHaveMail(group, user) { + newUser.Mail = fmt.Sprintf("%s@chalmers.it", user.Cid) + } else { + newUser.Mail = user.Email + } + + return newUser +} diff --git a/path b/path new file mode 100644 index 0000000..e69de29