Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Auth (Gamma 2.0) support #26

Merged
merged 3 commits into from
Jun 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 37 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
# GoldApps
# GoldApps

A system for syncing LDAP with gsuite and json files written in Go

### Features
* Migrate groups (from -> to):
* ldap -> gapps
* ldap -> json
* gapps -> json
* gapps -> gapps
* json -> gapps
* (json -> json)

Producers
- LDAP
- JSON
- Gamma (1.0)
- Auth (Gamma 2.0)

Consumers
- GApps
- JSON

## Dummy setup

Create the following files:

- `config.toml` - Copy from example.config.toml
- `gapps.json` - Containing `{}`
- `additions.json` - Containing `{}`
- `gamma.json` - Containing `{}`

## Setup
* Copy example.config.toml to config.toml and edit
* Grabb gapps.json and place in working directory
* go to [Google developer console](https://console.developers.google.com)
* go to credentials
* create new service account för this app
* use the downloaded file

- Copy example.config.toml to config.toml and edit
- Grabb gapps.json and place in working directory
- go to [Google developer console](https://console.developers.google.com)
- go to credentials
- create new service account för this app
- use the downloaded file

## Usage

Expand All @@ -30,19 +44,17 @@ For some reason `entrypoint` has to be specified in the compose file or the dock

The command should be your flags for the `goldapps` command

See `prod.docker-compose.yaml` as reference.

### Command `goldapps`

The following flags are available:
* `-y`: No interacting from the user required.
* `-i`: Ask the user about everything...
* `-dry`: Makes sure the program does not change anything.
* `-from someString`: Set the group source to `ldap`, `gapps` or `*.json`. In case of `gapps` config value `gapps.provider` will be used.
* `-to someString`: Set the group consumer to 'gapps' or '*.json'. In case of `gapps` config value `gapps.consumer` will be used.
* `-users`: Only collect and sync users
* `-groups`: Only collect and sync groups
* `-additions *.json`: file with additions

- `-y`: No interacting from the user required.
- `-i`: Ask the user about everything...
- `-dry`: Makes sure the program does not change anything.
- `-from someString`: Set the group source to `ldap`, `gapps` or `*.json`. In case of `gapps` config value `gapps.provider` will be used.
- `-to someString`: Set the group consumer to 'gapps' or '\*.json'. In case of `gapps` config value `gapps.consumer` will be used.
- `-users`: Only collect and sync users
- `-groups`: Only collect and sync groups
- `-additions *.json`: file with additions

Notice that flags should be combined on the form `goldapps -a -b` and **NOT** on the form `goldapps -ab`.
Notice that flags should be combined on the form `goldapps -a -b` and **NOT** on the form `goldapps -ab`.
14 changes: 14 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@ services:
POSTGRES_USER: user
POSTGRES_DB: postgres
POSTGRES_PASSWORD: password
networks:
- gamma-internal

gamma-frontend:
image: cthit/gamma-frontend:development
environment:
HTTP_PROXY: http://gamma-backend:8081
ports:
- 3000:3000
networks:
- gamma-internal

gamma-backend:
# Starta med cthit/gamma-backend:development för att få in mock data
Expand Down Expand Up @@ -43,6 +47,16 @@ services:
- ./mock.json:/mock/mock.json
ports:
- 8081:8081
networks:
- gamma
- gamma-internal

redis:
image: redis:5.0
networks:
- gamma-internal

networks:
gamma:
external: True
gamma-internal:
58 changes: 31 additions & 27 deletions example.config.toml
Original file line number Diff line number Diff line change
@@ -1,48 +1,52 @@
[gapps.consumer]
servicekeyfile = "gapps.json"
adminaccount = "[email protected]"
servicekeyfile = "gapps.json"
adminaccount = "[email protected]"

[gapps.provider]
servicekeyfile = "gapps.json"
adminaccount = "[email protected]"
servicekeyfile = "gapps.json"
adminaccount = "[email protected]"

[gamma.provider]
apiKey = "key"
url = "http://localhost:8081"
apiKey = "key"
url = "http://gamma-backend:8081"

[auth.provider]
apiKey = "key"
url = "http://gamma-mock:8081"

[additions]
file = "additions.json"

[ldap]
url = "ldap.mydomain.ex:636"
servername = "mydomain.ex"
user = "cn=admin,dc=mydomain,dc=ex"
password = "PASSWORD"
custom = ["fkit", "kit"]
url = "ldap.mydomain.ex:636"
servername = "mydomain.ex"
user = "cn=admin,dc=mydomain,dc=ex"
password = "PASSWORD"
custom = ["fkit", "kit"]

[ldap.groups]
basedn = "ou=groups,dc=mydomain,dc=ex"
filter = "(|(objectClass=itGroup)(objectClass=itPosition))"
attibutes = ["cn", "displayName", "mail", "member"]
basedn = "ou=groups,dc=mydomain,dc=ex"
filter = "(|(objectClass=itGroup)(objectClass=itPosition))"
attibutes = ["cn", "displayName", "mail", "member"]

[ldap.users]
basedn = "ou=people,dc=mydomain,dc=ex"
filter = "(&(objectClass=chalmersstudent))"
attibutes = ["uid", "mail"]
basedn = "ou=people,dc=mydomain,dc=ex"
filter = "(&(objectClass=chalmersstudent))"
attibutes = ["uid", "mail"]

#### CUSTOM FILTERS ####
[ldap.fkit]
mail = "[email protected]"
basedn = "ou=fkit,ou=groups,dc=mydomain,dc=ex"
filter = "(&(objectClass=itGroup))"
parent_filter = "(&(ou=%childRDN%))"
attibutes = ["cn", "displayName", "mail"]
mail = "[email protected]"
basedn = "ou=fkit,ou=groups,dc=mydomain,dc=ex"
filter = "(&(objectClass=itGroup))"
parent_filter = "(&(ou=%childRDN%))"
attibutes = ["cn", "displayName", "mail"]


[ldap.kit]
mail = "[email protected]"
basedn = "ou=fkit,ou=groups,dc=mydomain,dc=ex"
filter = "(&(objectClass=itGroup)(type=Committee))"
parent_filter = "(&(ou=%childRDN%))"
attibutes = ["cn", "displayName", "mail"]
mail = "[email protected]"
basedn = "ou=fkit,ou=groups,dc=mydomain,dc=ex"
filter = "(&(objectClass=itGroup)(type=Committee))"
parent_filter = "(&(ou=%childRDN%))"
attibutes = ["cn", "displayName", "mail"]
#### ============== ####
8 changes: 7 additions & 1 deletion internal/app/cli/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"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/auth"
"github.com/cthit/goldapps/internal/pkg/services/gamma"
"github.com/cthit/goldapps/internal/pkg/services/json"
"github.com/cthit/goldapps/internal/pkg/services/ldap"
Expand Down Expand Up @@ -80,7 +81,12 @@ func getProvider() services.CollectionService {
panic(err)
}
return provider

case "auth":
provider, _ := auth.CreateAuthService(
viper.GetString("auth.provider.apiKey"),
viper.GetString("auth.provider.url"),
)
return provider
default:
isJson, _ := regexp.MatchString(`.+\.json$`, from)
if isJson {
Expand Down
5 changes: 5 additions & 0 deletions internal/app/web/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"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/auth"
"github.com/cthit/goldapps/internal/pkg/services/gamma"
"github.com/cthit/goldapps/internal/pkg/services/json"
"github.com/spf13/viper"
Expand Down Expand Up @@ -48,6 +49,10 @@ func getProvider(fromJson string) (services.CollectionService, error) {
provider, err = gamma.CreateGammaService(
viper.GetString("gamma.provider.apiKey"),
viper.GetString("gamma.provider.url"))
} else if fromJson == "auth" {
provider, _ = auth.CreateAuthService(
viper.GetString("auth.provider.apiKey"),
viper.GetString("auth.provider.url"))
} else if isJson {
provider, err = json.NewJsonService(fromJson)
} else {
Expand Down
70 changes: 70 additions & 0 deletions internal/pkg/services/auth/models.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package auth

import "github.com/cthit/goldapps/internal/pkg/model"

type AuthSuperGroup struct {
Name string `json:"name"`
PrettyName string `json:"prettyName"`
Type string `json:"type"`
Members []struct {
Post struct {
PostID string `json:"postId"`
SvText string `json:"svText"`
EnText string `json:"enText"`
EmailPrefix string `json:"emailPrefix"`
} `json:"post"`
User AuthUser `json:"user"`
} `json:"members"`
}

type AuthUser struct {
Email string `json:"email"`
Cid string `json:"cid"`
FirstName string `json:"firstName"`
LastName string `json:"lastName"`
Nick string `json:"nick"`
}

type AuthSuperGroups []AuthSuperGroup

type AuthUsers []AuthUser

func (user AuthUser) ToUser() model.Users {
return model.Users{
model.User{
Cid: user.Cid,
FirstName: user.FirstName,
SecondName: user.LastName,
Nick: user.Nick,
Mail: user.Email,
},
}
}

func (users AuthUsers) ToUsers() model.Users {
usersList := model.Users{}
for _, user := range users {
usersList = append(usersList, user.ToUser()...)
}
return usersList
}

func (superGroup AuthSuperGroup) ToGroup() model.Group {
group := model.Group{
Email: superGroup.Name + "@chalmers.it",
Type: superGroup.Type,
Aliases: []string{},
}
for _, member := range superGroup.Members {
group.Members = append(group.Members, member.User.Email)
}
return group
}

func (superGroups AuthSuperGroups) ToGroups() model.Groups {
groupsList := model.Groups{}
for _, superGroup := range superGroups {
groupsList = append(groupsList, superGroup.ToGroup())
}
return groupsList
}
81 changes: 81 additions & 0 deletions internal/pkg/services/auth/service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package auth

import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"

"github.com/cthit/goldapps/internal/pkg/model"
)

type AuthService struct {
apiKey string
url string
}

// Creates a auth service which has the url to auth and the pre-shared key
func CreateAuthService(apiKey string, url string) (AuthService, error) {
return AuthService{
apiKey: apiKey,
url: url,
}, nil
}

// Executes a generic get request with api key
func request(s *AuthService, endpoint string, response interface{}) error {
req, err := http.NewRequest("GET", fmt.Sprintf("%s%s", s.url, 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
}
fmt.Printf("Request sent to: %s [key: %s] status %d\n", endpoint, s.apiKey, resp.StatusCode)

body, err := io.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
}

func (s AuthService) GetGroups() ([]model.Group, error) {
var groups AuthSuperGroups

err := request(&s, "/api/account-scaffold/v1/supergroups", &groups)
if err != nil {
log.Println(err)
return nil, err
}

return groups.ToGroups(), nil
}

func (s AuthService) GetUsers() ([]model.User, error) {
var users AuthUsers

err := request(&s, "/api/account-scaffold/v1/users", &users)
if err != nil {
log.Println(err)
return nil, err
}

return users.ToUsers(), nil
}
Loading
Loading