Skip to content

Commit b9e20b8

Browse files
authored
feat(control-plane): generate development user for head-less development (#1278)
Signed-off-by: Jose I. Paris <[email protected]>
1 parent 92de8af commit b9e20b8

File tree

6 files changed

+134
-71
lines changed

6 files changed

+134
-71
lines changed

app/controlplane/configs/config.devel.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ data:
5454

5555
# Development credentials for the SSO authentication roundtrip
5656
auth:
57+
dev_user: ${DEV_USER:}
5758
oidc:
5859
domain: ${DEX_DOMAIN:http://0.0.0.0:5556/dex}
5960
client_id: "chainloop-dev"

app/controlplane/internal/conf/controlplane/config/v1/conf.pb.go

+77-66
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/controlplane/internal/conf/controlplane/config/v1/conf.proto

+3
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,9 @@ message Auth {
137137
string cas_robot_account_private_key_path = 4;
138138
OIDC oidc = 6;
139139

140+
// Generates an initial user. Use only for development purposes
141+
string dev_user = 7;
142+
140143
message OIDC {
141144
string domain = 1;
142145
string client_id = 2;

app/controlplane/internal/service/auth.go

+33-3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/jwt/user"
3434
"github.com/chainloop-dev/chainloop/internal/oauth"
3535
sl "github.com/chainloop-dev/chainloop/pkg/servicelogger"
36+
"github.com/go-kratos/kratos/v2/log"
3637
"golang.org/x/oauth2"
3738
)
3839

@@ -52,7 +53,9 @@ const (
5253
// default
5354
shortLivedDuration = 10 * time.Second
5455
// opt-in
55-
logLivedDuration = 24 * time.Hour
56+
longLivedDuration = 24 * time.Hour
57+
// dev only
58+
devUserDuration = 30 * longLivedDuration
5659
)
5760

5861
type oauthHandler struct {
@@ -90,8 +93,16 @@ func NewAuthService(userUC *biz.UserUseCase, orgUC *biz.OrganizationUseCase, mUC
9093
return nil, fmt.Errorf("failed to create OIDC authenticator: %w", err)
9194
}
9295

96+
svc := newService(opts...)
97+
if authConfig.DevUser != "" {
98+
err := generateAndLogDevUser(userUC, svc.log, authConfig)
99+
if err != nil {
100+
return nil, fmt.Errorf("failed to create development user: %w", err)
101+
}
102+
}
103+
93104
return &AuthService{
94-
service: newService(opts...),
105+
service: svc,
95106
authenticator: authInst,
96107
userUseCase: userUC,
97108
orgUseCase: orgUC,
@@ -231,7 +242,7 @@ func callbackHandler(svc *AuthService, w http.ResponseWriter, r *http.Request) (
231242
}
232243

233244
if longLived.Value == "true" {
234-
expiration = logLivedDuration
245+
expiration = longLivedDuration
235246
}
236247

237248
// Generate user token
@@ -338,6 +349,25 @@ func setOauthCookie(w http.ResponseWriter, name, value string) {
338349
http.SetCookie(w, &http.Cookie{Name: name, Value: value, Path: "/", Expires: time.Now().Add(5 * time.Minute)})
339350
}
340351

352+
func generateAndLogDevUser(userUC *biz.UserUseCase, log *log.Helper, authConfig *conf.Auth) error {
353+
// Create user if needed
354+
u, err := userUC.FindOrCreateByEmail(context.Background(), authConfig.DevUser)
355+
if err != nil {
356+
return sl.LogAndMaskErr(err, log)
357+
}
358+
359+
// Generate user token
360+
userToken, err := generateUserJWT(u.ID, authConfig.GeneratedJwsHmacSecret, devUserDuration)
361+
if err != nil {
362+
return sl.LogAndMaskErr(err, log)
363+
}
364+
365+
log.Info("******************* DEVELOPMENT USER TOKEN *******************")
366+
log.Infof("Use chainloop 'auth login --skip-browser' and paste this token to start a headless session: %s", userToken)
367+
368+
return nil
369+
}
370+
341371
// DeleteAccount deletes an account
342372
func (svc *AuthService) DeleteAccount(ctx context.Context, _ *pb.AuthServiceDeleteAccountRequest) (*pb.AuthServiceDeleteAccountResponse, error) {
343373
user, err := requireCurrentUser(ctx)

devel/README.md

+17-2
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,25 @@ Configure the CLI to point to the local control plane and CAS services.
154154
chainloop config save --insecure --control-plane localhost:9000 --artifact-cas localhost:9001
155155
```
156156

157-
and login
157+
A new user and token has been created for you during bootstrap. An authentication token is available in the service logs (note that this is deactivated in production mode).
158+
Look for `DEVELOPMENT USER TOKEN` message in the container logs:
159+
```
160+
> docker compose -f compose.labs.yaml logs control-plane | grep -A 1 "DEVELOPMENT USER TOKEN"
161+
control-plane-1 | {"level":"info","ts":1724772518.38039,"component":"service","msg":"******************* DEVELOPMENT USER TOKEN *******************"}
162+
control-plane-1 | {"level":"info","ts":1724772518.3804584,"component":"service","msg":"Use chainloop 'auth login --skip-browser' and paste this token to start a headless session: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX2lkIjoiNzc4ZmExMzAtNjUzOS00ZTVmLThlYmYtMGQyZTkxYjRlNmM5IiwiaXNzIjoiY3AuY2hhaW5sb29wIiwiYXVkIjpbInVzZXItYXV0aC5jaGFpbmxvb3AiXSwiZXhwIjoxNzI3MzY0NTE4fQ.nyQtlR3bpc0VIna_UIKlXcx62gwG1dbuhkVm22fEXv4"}
163+
```
158164

165+
To authenticate, run this command and paste the token from the logs.
159166
```
160-
chainloop --insecure auth login
167+
> chainloop --insecure auth login --skip-browser
168+
WRN API contacted in insecure mode
169+
WRN Both user credentials and $CHAINLOOP_TOKEN set. Ignoring $CHAINLOOP_TOKEN.
170+
To authenticate, click on the following link and paste the result back here
171+
172+
http://0.0.0.0:8000/auth/login?long-lived=true
173+
174+
Enter Token:
175+
INF login successful!
161176
```
162177

163178
you are now ready to use the CLI and follow the [quickstart guide](https://docs.chainloop.dev/quickstart)

devel/compose.labs.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ services:
2323
CP_FILE_CA_CERT_PATH: /devkeys/ca.pub
2424
CP_FILE_CA_KEY_PATH: /devkeys/ca.pem
2525
CP_CAS_KEY_PATH: /devkeys/cas.pem
26+
CP_DEV_USER: [email protected]
2627
volumes:
2728
# main configuration
2829
- ../app/controlplane/configs:/data/conf
@@ -32,6 +33,8 @@ services:
3233
- 9000:9000
3334
- 8000:8000
3435
depends_on:
36+
dex:
37+
condition: service_started
3538
vault:
3639
condition: service_started
3740
db-init:

0 commit comments

Comments
 (0)