mirror of
https://github.com/khairul169/vaulterm.git
synced 2025-04-28 16:49:39 +07:00
feat: add gitlab oauth, cleanup code
This commit is contained in:
parent
a6cc450ea7
commit
83d0ed380d
@ -5,5 +5,10 @@ DATABASE_URL=
|
|||||||
ENCRYPTION_KEY=""
|
ENCRYPTION_KEY=""
|
||||||
|
|
||||||
# OAuth client
|
# OAuth client
|
||||||
|
OAUTH_ENABLED=github,gitlab
|
||||||
|
|
||||||
GITHUB_CLIENT_ID=
|
GITHUB_CLIENT_ID=
|
||||||
GITHUB_CLIENT_SECRET=
|
GITHUB_CLIENT_SECRET=
|
||||||
|
|
||||||
|
GITLAB_CLIENT_ID=
|
||||||
|
GITLAB_CLIENT_SECRET=
|
||||||
|
43
frontend/pages/auth/components/login-gitlab.tsx
Normal file
43
frontend/pages/auth/components/login-gitlab.tsx
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import React, { useEffect, useMemo } from "react";
|
||||||
|
import { useAuthRequest } from "expo-auth-session";
|
||||||
|
import { Button } from "tamagui";
|
||||||
|
import { useOAuthCallback } from "../hooks";
|
||||||
|
import { useServerConfig } from "@/hooks/useServerConfig";
|
||||||
|
|
||||||
|
const LoginGitlabButton = () => {
|
||||||
|
const { data: clientId } = useServerConfig("gitlab_client_id");
|
||||||
|
const discovery = useMemo(() => {
|
||||||
|
return {
|
||||||
|
authorizationEndpoint: "https://gitlab.com/oauth/authorize",
|
||||||
|
tokenEndpoint: "https://gitlab.com/oauth/token",
|
||||||
|
revocationEndpoint: "https://gitlab.com/oauth/revoke",
|
||||||
|
};
|
||||||
|
}, [clientId]);
|
||||||
|
const oauth = useOAuthCallback("gitlab");
|
||||||
|
|
||||||
|
const [request, response, promptAsync] = useAuthRequest(
|
||||||
|
{
|
||||||
|
clientId,
|
||||||
|
scopes: ["read_user"],
|
||||||
|
// redirectUri: makeRedirectUri({ scheme: appConfig.scheme }),
|
||||||
|
redirectUri: "http://localhost:8081",
|
||||||
|
},
|
||||||
|
discovery
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (response?.type === "success") {
|
||||||
|
const { code } = response.params;
|
||||||
|
const verifier = request?.codeVerifier;
|
||||||
|
oauth.mutate({ code, verifier });
|
||||||
|
}
|
||||||
|
}, [response]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button disabled={!request} onPress={() => promptAsync()}>
|
||||||
|
Login with Gitlab
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LoginGitlabButton;
|
@ -1,4 +1,4 @@
|
|||||||
import { useMutation } from "@tanstack/react-query";
|
import { useMutation, useQuery } from "@tanstack/react-query";
|
||||||
import {
|
import {
|
||||||
loginResultSchema,
|
loginResultSchema,
|
||||||
LoginSchema,
|
LoginSchema,
|
||||||
@ -45,8 +45,8 @@ export const useRegisterMutation = () => {
|
|||||||
|
|
||||||
export const useOAuthCallback = (type: string) => {
|
export const useOAuthCallback = (type: string) => {
|
||||||
return useMutation({
|
return useMutation({
|
||||||
mutationFn: async (code: string) => {
|
mutationFn: async (params: { code: string; verifier?: string }) => {
|
||||||
const res = await api(`/auth/oauth/${type}/callback?code=${code}`);
|
const res = await api(`/auth/oauth/${type}/callback`, { params });
|
||||||
const { data } = loginResultSchema.safeParse(res);
|
const { data } = loginResultSchema.safeParse(res);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
throw new Error("Invalid response!");
|
throw new Error("Invalid response!");
|
||||||
|
@ -14,6 +14,7 @@ import tamaguiConfig from "@/tamagui.config";
|
|||||||
import { useLoginMutation } from "./hooks";
|
import { useLoginMutation } from "./hooks";
|
||||||
import LoginGithubButton from "./components/login-github";
|
import LoginGithubButton from "./components/login-github";
|
||||||
import { useServerConfig } from "@/hooks/useServerConfig";
|
import { useServerConfig } from "@/hooks/useServerConfig";
|
||||||
|
import LoginGitlabButton from "./components/login-gitlab";
|
||||||
|
|
||||||
WebBrowser.maybeCompleteAuthSession();
|
WebBrowser.maybeCompleteAuthSession();
|
||||||
|
|
||||||
@ -109,6 +110,7 @@ export default function LoginPage() {
|
|||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
{oauthList.includes("github") && <LoginGithubButton />}
|
{oauthList.includes("github") && <LoginGithubButton />}
|
||||||
|
{oauthList.includes("gitlab") && <LoginGitlabButton />}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@ -16,21 +16,22 @@ import (
|
|||||||
"rul.sh/vaulterm/server/utils"
|
"rul.sh/vaulterm/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var config *oauth2.Config
|
var githubCfg *oauth2.Config
|
||||||
|
|
||||||
func getGithubConfig() *oauth2.Config {
|
func getGithubConfig() *oauth2.Config {
|
||||||
if config != nil {
|
if githubCfg != nil {
|
||||||
return config
|
return githubCfg
|
||||||
}
|
}
|
||||||
|
|
||||||
config = &oauth2.Config{
|
githubCfg = &oauth2.Config{
|
||||||
ClientID: os.Getenv("GITHUB_CLIENT_ID"),
|
ClientID: os.Getenv("GITHUB_CLIENT_ID"),
|
||||||
ClientSecret: os.Getenv("GITHUB_CLIENT_SECRET"),
|
ClientSecret: os.Getenv("GITHUB_CLIENT_SECRET"),
|
||||||
Endpoint: github.Endpoint,
|
Endpoint: github.Endpoint,
|
||||||
RedirectURL: "http://localhost:3000/auth/oauth/github/callback",
|
// RedirectURL: "http://localhost:3000/auth/oauth/github/callback",
|
||||||
Scopes: []string{"read:user"},
|
RedirectURL: "http://localhost:8081",
|
||||||
|
Scopes: []string{"read:user"},
|
||||||
}
|
}
|
||||||
return config
|
return githubCfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func githubRedir(c *fiber.Ctx) error {
|
func githubRedir(c *fiber.Ctx) error {
|
||||||
|
147
server/app/auth/oauth_gitlab.go
Normal file
147
server/app/auth/oauth_gitlab.go
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
"golang.org/x/oauth2/gitlab"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"rul.sh/vaulterm/server/models"
|
||||||
|
"rul.sh/vaulterm/server/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GitlabCfg struct {
|
||||||
|
oauth2.Config
|
||||||
|
verifier string
|
||||||
|
challenge string
|
||||||
|
}
|
||||||
|
|
||||||
|
var gitlabCfg *GitlabCfg
|
||||||
|
|
||||||
|
func getGitlabConfig() *GitlabCfg {
|
||||||
|
if gitlabCfg != nil {
|
||||||
|
return gitlabCfg
|
||||||
|
}
|
||||||
|
|
||||||
|
oauthCfg := oauth2.Config{
|
||||||
|
ClientID: os.Getenv("GITLAB_CLIENT_ID"),
|
||||||
|
ClientSecret: os.Getenv("GITLAB_CLIENT_SECRET"),
|
||||||
|
Endpoint: gitlab.Endpoint,
|
||||||
|
// RedirectURL: "http://localhost:3000/auth/oauth/gitlab/callback",
|
||||||
|
RedirectURL: "http://localhost:8081",
|
||||||
|
Scopes: []string{"read_user"},
|
||||||
|
}
|
||||||
|
verifier := oauth2.GenerateVerifier()
|
||||||
|
challenge := oauth2.S256ChallengeFromVerifier(verifier)
|
||||||
|
|
||||||
|
gitlabCfg = &GitlabCfg{
|
||||||
|
Config: oauthCfg,
|
||||||
|
verifier: verifier,
|
||||||
|
challenge: challenge,
|
||||||
|
}
|
||||||
|
return gitlabCfg
|
||||||
|
}
|
||||||
|
|
||||||
|
func gitlabRedir(c *fiber.Ctx) error {
|
||||||
|
// Redirect to Gitlab login page
|
||||||
|
url := getGitlabConfig().
|
||||||
|
AuthCodeURL("login", oauth2.S256ChallengeOption(getGitlabConfig().verifier))
|
||||||
|
return c.Redirect(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
func gitlabCallback(c *fiber.Ctx) error {
|
||||||
|
cfg := getGitlabConfig()
|
||||||
|
code := c.Query("code")
|
||||||
|
verifier := c.Query("verifier")
|
||||||
|
|
||||||
|
if code == "" {
|
||||||
|
return c.Status(fiber.StatusBadRequest).SendString("Missing code")
|
||||||
|
}
|
||||||
|
if verifier == "" {
|
||||||
|
verifier = cfg.verifier
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exchange code for a token
|
||||||
|
token, err := cfg.Exchange(c.Context(), code, oauth2.VerifierOption(verifier))
|
||||||
|
if err != nil {
|
||||||
|
log.Println(token, err)
|
||||||
|
return c.Status(fiber.StatusInternalServerError).SendString("Failed to exchange token")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve user info
|
||||||
|
client := cfg.Client(c.Context(), token)
|
||||||
|
resp, err := client.Get("https://gitlab.com/api/v4/user")
|
||||||
|
if err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).SendString("Failed to get user info")
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, _ := io.ReadAll(resp.Body)
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).
|
||||||
|
SendString(fmt.Sprintf("Gitlab API error: %s", string(body)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse user info
|
||||||
|
var user struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
AvatarURL string `json:"avatar_url"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(body, &user); err != nil {
|
||||||
|
return c.Status(fiber.StatusInternalServerError).SendString("Failed to parse user info")
|
||||||
|
}
|
||||||
|
|
||||||
|
repo := NewRepository()
|
||||||
|
accountId := strconv.Itoa(user.ID)
|
||||||
|
userAccount, err := repo.FindUserAccount("gitlab", accountId)
|
||||||
|
|
||||||
|
// Register the user if the account not yet registered
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
acc := models.UserAccount{
|
||||||
|
Type: "gitlab",
|
||||||
|
AccountID: accountId,
|
||||||
|
Username: user.Username,
|
||||||
|
Email: user.Email,
|
||||||
|
}
|
||||||
|
user := models.User{
|
||||||
|
Name: user.Name,
|
||||||
|
Role: models.UserRoleUser,
|
||||||
|
Image: user.AvatarURL,
|
||||||
|
Accounts: []*models.UserAccount{&acc},
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionId, err := repo.CreateUser(&user)
|
||||||
|
if err != nil {
|
||||||
|
return utils.ResponseError(c, err, 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(fiber.Map{
|
||||||
|
"user": user,
|
||||||
|
"sessionId": sessionId,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return utils.ResponseError(c, err, 500)
|
||||||
|
}
|
||||||
|
sessionId, err := repo.CreateUserSession(&userAccount.User)
|
||||||
|
if err != nil {
|
||||||
|
return utils.ResponseError(c, err, 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(fiber.Map{
|
||||||
|
"user": userAccount.User,
|
||||||
|
"sessionId": sessionId,
|
||||||
|
})
|
||||||
|
}
|
@ -3,8 +3,8 @@ package auth
|
|||||||
import (
|
import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"rul.sh/vaulterm/server/db"
|
"rul.sh/vaulterm/server/db"
|
||||||
"rul.sh/vaulterm/server/lib"
|
|
||||||
"rul.sh/vaulterm/server/models"
|
"rul.sh/vaulterm/server/models"
|
||||||
|
"rul.sh/vaulterm/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Auth struct{ db *gorm.DB }
|
type Auth struct{ db *gorm.DB }
|
||||||
@ -30,7 +30,7 @@ func (r *Auth) FindUserAccount(accountType string, accountId string) (*models.Us
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *Auth) CreateUserSession(user *models.User) (string, error) {
|
func (r *Auth) CreateUserSession(user *models.User) (string, error) {
|
||||||
sessionId, err := lib.GenerateSessionID(20)
|
sessionId, err := utils.GenerateSessionID(20)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ func Router(app *fiber.App) {
|
|||||||
oauth := router.Group("/oauth")
|
oauth := router.Group("/oauth")
|
||||||
oauth.Get("/github", githubRedir)
|
oauth.Get("/github", githubRedir)
|
||||||
oauth.Get("/github/callback", githubCallback)
|
oauth.Get("/github/callback", githubCallback)
|
||||||
|
oauth.Get("/gitlab", gitlabRedir)
|
||||||
|
oauth.Get("/gitlab/callback", gitlabCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
func login(c *fiber.Ctx) error {
|
func login(c *fiber.Ctx) error {
|
||||||
@ -40,7 +42,7 @@ func login(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if valid := lib.VerifyPassword(body.Password, user.Password); !valid {
|
if valid := utils.VerifyPassword(body.Password, user.Password); !valid {
|
||||||
return &fiber.Error{
|
return &fiber.Error{
|
||||||
Code: fiber.StatusUnauthorized,
|
Code: fiber.StatusUnauthorized,
|
||||||
Message: "Username or password is invalid",
|
Message: "Username or password is invalid",
|
||||||
@ -59,7 +61,7 @@ func login(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getUser(c *fiber.Ctx) error {
|
func getUser(c *fiber.Ctx) error {
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
teams := []TeamWithRole{}
|
teams := []TeamWithRole{}
|
||||||
|
|
||||||
for _, item := range user.Teams {
|
for _, item := range user.Teams {
|
||||||
@ -96,15 +98,15 @@ func register(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
password, err := lib.HashPassword(body.Password)
|
password, err := utils.HashPassword(body.Password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.ResponseError(c, err, 500)
|
return utils.ResponseError(c, err, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
user := &models.User{
|
user := &models.User{
|
||||||
Name: body.Name,
|
Name: body.Name,
|
||||||
Username: body.Username,
|
Username: &body.Username,
|
||||||
Email: body.Email,
|
Email: &body.Email,
|
||||||
Password: password,
|
Password: password,
|
||||||
Role: models.UserRoleUser,
|
Role: models.UserRoleUser,
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,13 @@ package hosts
|
|||||||
import (
|
import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"rul.sh/vaulterm/server/db"
|
"rul.sh/vaulterm/server/db"
|
||||||
|
"rul.sh/vaulterm/server/lib"
|
||||||
"rul.sh/vaulterm/server/models"
|
"rul.sh/vaulterm/server/models"
|
||||||
"rul.sh/vaulterm/server/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Hosts struct {
|
type Hosts struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
User *utils.UserContext
|
User *lib.UserContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRepository(r *Hosts) *Hosts {
|
func NewRepository(r *Hosts) *Hosts {
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"rul.sh/vaulterm/server/lib"
|
||||||
"rul.sh/vaulterm/server/models"
|
"rul.sh/vaulterm/server/models"
|
||||||
"rul.sh/vaulterm/server/utils"
|
"rul.sh/vaulterm/server/utils"
|
||||||
)
|
)
|
||||||
@ -25,7 +26,7 @@ func getAll(c *fiber.Ctx) error {
|
|||||||
teamId := c.Query("teamId")
|
teamId := c.Query("teamId")
|
||||||
parentId := c.Query("parentId")
|
parentId := c.Query("parentId")
|
||||||
|
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
repo := NewRepository(&Hosts{User: user})
|
repo := NewRepository(&Hosts{User: user})
|
||||||
|
|
||||||
if teamId != "" && !user.IsInTeam(&teamId) {
|
if teamId != "" && !user.IsInTeam(&teamId) {
|
||||||
@ -48,7 +49,7 @@ func create(c *fiber.Ctx) error {
|
|||||||
return utils.ResponseError(c, err, 500)
|
return utils.ResponseError(c, err, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
repo := NewRepository(&Hosts{User: user})
|
repo := NewRepository(&Hosts{User: user})
|
||||||
|
|
||||||
if body.TeamID != nil && !user.TeamCanWrite(body.TeamID) {
|
if body.TeamID != nil && !user.TeamCanWrite(body.TeamID) {
|
||||||
@ -87,7 +88,7 @@ func update(c *fiber.Ctx) error {
|
|||||||
return utils.ResponseError(c, err, 500)
|
return utils.ResponseError(c, err, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
repo := NewRepository(&Hosts{User: user})
|
repo := NewRepository(&Hosts{User: user})
|
||||||
|
|
||||||
id := c.Params("id")
|
id := c.Params("id")
|
||||||
@ -126,7 +127,7 @@ func update(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func delete(c *fiber.Ctx) error {
|
func delete(c *fiber.Ctx) error {
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
repo := NewRepository(&Hosts{User: user})
|
repo := NewRepository(&Hosts{User: user})
|
||||||
|
|
||||||
id := c.Params("id")
|
id := c.Params("id")
|
||||||
@ -149,7 +150,7 @@ func delete(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func move(c *fiber.Ctx) error {
|
func move(c *fiber.Ctx) error {
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
repo := NewRepository(&Hosts{User: user})
|
repo := NewRepository(&Hosts{User: user})
|
||||||
|
|
||||||
// validate request
|
// validate request
|
||||||
|
@ -7,11 +7,10 @@ import (
|
|||||||
"rul.sh/vaulterm/server/app/keychains"
|
"rul.sh/vaulterm/server/app/keychains"
|
||||||
"rul.sh/vaulterm/server/lib"
|
"rul.sh/vaulterm/server/lib"
|
||||||
"rul.sh/vaulterm/server/models"
|
"rul.sh/vaulterm/server/models"
|
||||||
"rul.sh/vaulterm/server/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func tryConnect(c *fiber.Ctx, host *models.Host) (string, error) {
|
func tryConnect(c *fiber.Ctx, host *models.Host) (string, error) {
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
keyRepo := keychains.NewRepository(&keychains.Keychains{User: user})
|
keyRepo := keychains.NewRepository(&keychains.Keychains{User: user})
|
||||||
|
|
||||||
var key map[string]interface{}
|
var key map[string]interface{}
|
||||||
|
@ -3,13 +3,13 @@ package keychains
|
|||||||
import (
|
import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"rul.sh/vaulterm/server/db"
|
"rul.sh/vaulterm/server/db"
|
||||||
|
"rul.sh/vaulterm/server/lib"
|
||||||
"rul.sh/vaulterm/server/models"
|
"rul.sh/vaulterm/server/models"
|
||||||
"rul.sh/vaulterm/server/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Keychains struct {
|
type Keychains struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
User *utils.UserContext
|
User *lib.UserContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRepository(r *Keychains) *Keychains {
|
func NewRepository(r *Keychains) *Keychains {
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"rul.sh/vaulterm/server/lib"
|
||||||
"rul.sh/vaulterm/server/models"
|
"rul.sh/vaulterm/server/models"
|
||||||
"rul.sh/vaulterm/server/utils"
|
"rul.sh/vaulterm/server/utils"
|
||||||
)
|
)
|
||||||
@ -26,7 +27,7 @@ func getAll(c *fiber.Ctx) error {
|
|||||||
teamId := c.Query("teamId")
|
teamId := c.Query("teamId")
|
||||||
withData := c.Query("withData")
|
withData := c.Query("withData")
|
||||||
|
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
repo := NewRepository(&Keychains{User: user})
|
repo := NewRepository(&Keychains{User: user})
|
||||||
|
|
||||||
if teamId != "" && !user.IsInTeam(&teamId) {
|
if teamId != "" && !user.IsInTeam(&teamId) {
|
||||||
@ -69,7 +70,7 @@ func create(c *fiber.Ctx) error {
|
|||||||
return utils.ResponseError(c, err, 500)
|
return utils.ResponseError(c, err, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
repo := NewRepository(&Keychains{User: user})
|
repo := NewRepository(&Keychains{User: user})
|
||||||
|
|
||||||
if body.TeamID != nil && !user.TeamCanWrite(body.TeamID) {
|
if body.TeamID != nil && !user.TeamCanWrite(body.TeamID) {
|
||||||
@ -100,7 +101,7 @@ func update(c *fiber.Ctx) error {
|
|||||||
return utils.ResponseError(c, err, 500)
|
return utils.ResponseError(c, err, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
repo := NewRepository(&Keychains{User: user})
|
repo := NewRepository(&Keychains{User: user})
|
||||||
|
|
||||||
id := c.Params("id")
|
id := c.Params("id")
|
||||||
|
@ -22,8 +22,9 @@ func getServerInfo(c *fiber.Ctx) error {
|
|||||||
|
|
||||||
func getConfig(c *fiber.Ctx) error {
|
func getConfig(c *fiber.Ctx) error {
|
||||||
config := fiber.Map{
|
config := fiber.Map{
|
||||||
"oauth": "github",
|
"oauth": os.Getenv("OAUTH_ENABLED"),
|
||||||
"github_client_id": os.Getenv("GITHUB_CLIENT_ID"),
|
"github_client_id": os.Getenv("GITHUB_CLIENT_ID"),
|
||||||
|
"gitlab_client_id": os.Getenv("GITLAB_CLIENT_ID"),
|
||||||
}
|
}
|
||||||
return c.JSON(config)
|
return c.JSON(config)
|
||||||
}
|
}
|
||||||
|
@ -4,13 +4,13 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/clause"
|
"gorm.io/gorm/clause"
|
||||||
"rul.sh/vaulterm/server/db"
|
"rul.sh/vaulterm/server/db"
|
||||||
|
"rul.sh/vaulterm/server/lib"
|
||||||
"rul.sh/vaulterm/server/models"
|
"rul.sh/vaulterm/server/models"
|
||||||
"rul.sh/vaulterm/server/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type TeamMembers struct {
|
type TeamMembers struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
User *utils.UserContext
|
User *lib.UserContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRepository(r *TeamMembers) *TeamMembers {
|
func NewRepository(r *TeamMembers) *TeamMembers {
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"rul.sh/vaulterm/server/app/teams"
|
"rul.sh/vaulterm/server/app/teams"
|
||||||
"rul.sh/vaulterm/server/app/users"
|
"rul.sh/vaulterm/server/app/users"
|
||||||
|
"rul.sh/vaulterm/server/lib"
|
||||||
"rul.sh/vaulterm/server/models"
|
"rul.sh/vaulterm/server/models"
|
||||||
"rul.sh/vaulterm/server/utils"
|
"rul.sh/vaulterm/server/utils"
|
||||||
)
|
)
|
||||||
@ -20,7 +21,7 @@ func Router(app fiber.Router) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// func getAll(c *fiber.Ctx) error {
|
// func getAll(c *fiber.Ctx) error {
|
||||||
// user := utils.GetUser(c)
|
// user := lib.GetUser(c)
|
||||||
// repo := NewRepository(&TeamMembers{User: user})
|
// repo := NewRepository(&TeamMembers{User: user})
|
||||||
|
|
||||||
// rows, err := repo.GetAll()
|
// rows, err := repo.GetAll()
|
||||||
@ -37,7 +38,7 @@ func invite(c *fiber.Ctx) error {
|
|||||||
return utils.ResponseError(c, err, 500)
|
return utils.ResponseError(c, err, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
teamRepo := teams.NewRepository(&teams.Teams{User: user})
|
teamRepo := teams.NewRepository(&teams.Teams{User: user})
|
||||||
repo := NewRepository(&TeamMembers{User: user})
|
repo := NewRepository(&TeamMembers{User: user})
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ func setRole(c *fiber.Ctx) error {
|
|||||||
return utils.ResponseError(c, err, 500)
|
return utils.ResponseError(c, err, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
teamRepo := teams.NewRepository(&teams.Teams{User: user})
|
teamRepo := teams.NewRepository(&teams.Teams{User: user})
|
||||||
repo := NewRepository(&TeamMembers{User: user})
|
repo := NewRepository(&TeamMembers{User: user})
|
||||||
|
|
||||||
@ -103,7 +104,7 @@ func setRole(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func remove(c *fiber.Ctx) error {
|
func remove(c *fiber.Ctx) error {
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
teamRepo := teams.NewRepository(&teams.Teams{User: user})
|
teamRepo := teams.NewRepository(&teams.Teams{User: user})
|
||||||
repo := NewRepository(&TeamMembers{User: user})
|
repo := NewRepository(&TeamMembers{User: user})
|
||||||
|
|
||||||
|
@ -3,13 +3,13 @@ package teams
|
|||||||
import (
|
import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"rul.sh/vaulterm/server/db"
|
"rul.sh/vaulterm/server/db"
|
||||||
|
"rul.sh/vaulterm/server/lib"
|
||||||
"rul.sh/vaulterm/server/models"
|
"rul.sh/vaulterm/server/models"
|
||||||
"rul.sh/vaulterm/server/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Teams struct {
|
type Teams struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
User *utils.UserContext
|
User *lib.UserContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRepository(r *Teams) *Teams {
|
func NewRepository(r *Teams) *Teams {
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
"rul.sh/vaulterm/server/lib"
|
||||||
"rul.sh/vaulterm/server/models"
|
"rul.sh/vaulterm/server/models"
|
||||||
"rul.sh/vaulterm/server/utils"
|
"rul.sh/vaulterm/server/utils"
|
||||||
)
|
)
|
||||||
@ -22,7 +23,7 @@ func Router(app fiber.Router) fiber.Router {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getAll(c *fiber.Ctx) error {
|
func getAll(c *fiber.Ctx) error {
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
repo := NewRepository(&Teams{User: user})
|
repo := NewRepository(&Teams{User: user})
|
||||||
|
|
||||||
rows, err := repo.GetAll()
|
rows, err := repo.GetAll()
|
||||||
@ -34,7 +35,7 @@ func getAll(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getById(c *fiber.Ctx) error {
|
func getById(c *fiber.Ctx) error {
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
repo := NewRepository(&Teams{User: user})
|
repo := NewRepository(&Teams{User: user})
|
||||||
|
|
||||||
id := c.Params("id")
|
id := c.Params("id")
|
||||||
@ -52,7 +53,7 @@ func create(c *fiber.Ctx) error {
|
|||||||
return utils.ResponseError(c, err, 500)
|
return utils.ResponseError(c, err, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
repo := NewRepository(&Teams{User: user})
|
repo := NewRepository(&Teams{User: user})
|
||||||
|
|
||||||
item := &models.Team{
|
item := &models.Team{
|
||||||
@ -73,7 +74,7 @@ func update(c *fiber.Ctx) error {
|
|||||||
return utils.ResponseError(c, err, 500)
|
return utils.ResponseError(c, err, 500)
|
||||||
}
|
}
|
||||||
|
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
repo := NewRepository(&Teams{User: user})
|
repo := NewRepository(&Teams{User: user})
|
||||||
|
|
||||||
id := c.Params("id")
|
id := c.Params("id")
|
||||||
@ -98,7 +99,7 @@ func update(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func delete(c *fiber.Ctx) error {
|
func delete(c *fiber.Ctx) error {
|
||||||
user := utils.GetUser(c)
|
user := lib.GetUser(c)
|
||||||
repo := NewRepository(&Teams{User: user})
|
repo := NewRepository(&Teams{User: user})
|
||||||
|
|
||||||
id := c.Params("id")
|
id := c.Params("id")
|
||||||
|
@ -3,13 +3,13 @@ package users
|
|||||||
import (
|
import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"rul.sh/vaulterm/server/db"
|
"rul.sh/vaulterm/server/db"
|
||||||
|
"rul.sh/vaulterm/server/lib"
|
||||||
"rul.sh/vaulterm/server/models"
|
"rul.sh/vaulterm/server/models"
|
||||||
"rul.sh/vaulterm/server/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Users struct {
|
type Users struct {
|
||||||
db *gorm.DB
|
db *gorm.DB
|
||||||
User *utils.UserContext
|
User *lib.UserContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewRepository(r *Users) *Users {
|
func NewRepository(r *Users) *Users {
|
||||||
|
@ -5,13 +5,12 @@ import (
|
|||||||
"rul.sh/vaulterm/server/app/hosts"
|
"rul.sh/vaulterm/server/app/hosts"
|
||||||
"rul.sh/vaulterm/server/lib"
|
"rul.sh/vaulterm/server/lib"
|
||||||
"rul.sh/vaulterm/server/models"
|
"rul.sh/vaulterm/server/models"
|
||||||
"rul.sh/vaulterm/server/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func HandleStats(c *websocket.Conn) {
|
func HandleStats(c *websocket.Conn) {
|
||||||
hostId := c.Query("hostId")
|
hostId := c.Query("hostId")
|
||||||
|
|
||||||
user := utils.GetUserWs(c)
|
user := lib.GetUserWs(c)
|
||||||
hostRepo := hosts.NewRepository(&hosts.Hosts{User: user})
|
hostRepo := hosts.NewRepository(&hosts.Hosts{User: user})
|
||||||
data, _ := hostRepo.GetWithKeys(hostId)
|
data, _ := hostRepo.GetWithKeys(hostId)
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
func HandleTerm(c *websocket.Conn) {
|
func HandleTerm(c *websocket.Conn) {
|
||||||
hostId := c.Query("hostId")
|
hostId := c.Query("hostId")
|
||||||
|
|
||||||
user := utils.GetUserWs(c)
|
user := lib.GetUserWs(c)
|
||||||
hostRepo := hosts.NewRepository(&hosts.Hosts{User: user})
|
hostRepo := hosts.NewRepository(&hosts.Hosts{User: user})
|
||||||
data, err := hostRepo.GetWithKeys(hostId)
|
data, err := hostRepo.GetWithKeys(hostId)
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@ package db
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"rul.sh/vaulterm/server/lib"
|
|
||||||
"rul.sh/vaulterm/server/models"
|
"rul.sh/vaulterm/server/models"
|
||||||
|
"rul.sh/vaulterm/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SeedFn func(*gorm.DB) error
|
type SeedFn func(*gorm.DB) error
|
||||||
@ -23,7 +23,7 @@ func seedUsers(tx *gorm.DB) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
testPasswd, err := lib.HashPassword("123456")
|
testPasswd, err := utils.HashPassword("123456")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -42,38 +42,38 @@ func seedUsers(tx *gorm.DB) error {
|
|||||||
userList := []*models.User{
|
userList := []*models.User{
|
||||||
{
|
{
|
||||||
Name: "Admin",
|
Name: "Admin",
|
||||||
Username: "admin",
|
Username: utils.StringPtr("admin"),
|
||||||
Password: testPasswd,
|
Password: testPasswd,
|
||||||
Email: "admin@mail.com",
|
Email: utils.StringPtr("admin@mail.com"),
|
||||||
Role: models.UserRoleAdmin,
|
Role: models.UserRoleAdmin,
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
Name: "John Doe",
|
// Name: "John Doe",
|
||||||
Username: "user",
|
// Username: "user",
|
||||||
Password: testPasswd,
|
// Password: testPasswd,
|
||||||
Email: "user@mail.com",
|
// Email: "user@mail.com",
|
||||||
},
|
// },
|
||||||
{
|
// {
|
||||||
Name: "Mary Doe",
|
// Name: "Mary Doe",
|
||||||
Username: "user2",
|
// Username: "user2",
|
||||||
Password: testPasswd,
|
// Password: testPasswd,
|
||||||
Email: "user2@mail.com",
|
// Email: "user2@mail.com",
|
||||||
},
|
// },
|
||||||
}
|
}
|
||||||
|
|
||||||
if res := tx.Create(&userList); res.Error != nil {
|
if res := tx.Create(&userList); res.Error != nil {
|
||||||
return res.Error
|
return res.Error
|
||||||
}
|
}
|
||||||
|
|
||||||
teamMembers := []models.TeamMembers{
|
// teamMembers := []models.TeamMembers{
|
||||||
{TeamID: teams[0].ID, UserID: userList[0].ID, Role: models.TeamRoleOwner},
|
// {TeamID: teams[0].ID, UserID: userList[0].ID, Role: models.TeamRoleOwner},
|
||||||
{TeamID: teams[0].ID, UserID: userList[1].ID, Role: models.TeamRoleAdmin},
|
// {TeamID: teams[0].ID, UserID: userList[1].ID, Role: models.TeamRoleAdmin},
|
||||||
{TeamID: teams[0].ID, UserID: userList[2].ID, Role: models.TeamRoleMember},
|
// {TeamID: teams[0].ID, UserID: userList[2].ID, Role: models.TeamRoleMember},
|
||||||
}
|
// }
|
||||||
|
|
||||||
if res := tx.Create(&teamMembers); res.Error != nil {
|
// if res := tx.Create(&teamMembers); res.Error != nil {
|
||||||
return res.Error
|
// return res.Error
|
||||||
}
|
// }
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package utils
|
package lib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gofiber/contrib/websocket"
|
"github.com/gofiber/contrib/websocket"
|
@ -8,6 +8,8 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"rul.sh/vaulterm/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type IncusServer struct {
|
type IncusServer struct {
|
||||||
@ -22,7 +24,7 @@ type IncusFetchConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (i *IncusServer) GetCertificate() (*tls.Certificate, error) {
|
func (i *IncusServer) GetCertificate() (*tls.Certificate, error) {
|
||||||
return LoadClientCertificate(i.ClientCert, i.ClientKey)
|
return utils.LoadClientCertificate(i.ClientCert, i.ClientKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *IncusServer) Fetch(method string, url string, cfg *IncusFetchConfig) ([]byte, error) {
|
func (i *IncusServer) Fetch(method string, url string, cfg *IncusFetchConfig) ([]byte, error) {
|
||||||
|
@ -3,7 +3,7 @@ package models
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"rul.sh/vaulterm/server/lib"
|
"rul.sh/vaulterm/server/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -36,7 +36,7 @@ func (k *Keychain) EncryptData(data interface{}) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
enc, err := lib.Encrypt(string(jsonData))
|
enc, err := utils.Encrypt(string(jsonData))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
k.Data = enc
|
k.Data = enc
|
||||||
}
|
}
|
||||||
@ -45,7 +45,7 @@ func (k *Keychain) EncryptData(data interface{}) error {
|
|||||||
|
|
||||||
func (k *Keychain) DecryptData(data interface{}) error {
|
func (k *Keychain) DecryptData(data interface{}) error {
|
||||||
// Decrypt stored data
|
// Decrypt stored data
|
||||||
dec, err := lib.Decrypt(k.Data)
|
dec, err := utils.Decrypt(k.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -12,12 +12,12 @@ const (
|
|||||||
type User struct {
|
type User struct {
|
||||||
Model
|
Model
|
||||||
|
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Username string `json:"username" gorm:"unique"`
|
Username *string `json:"username" gorm:"unique"`
|
||||||
Password string `json:"-"`
|
Password string `json:"-"`
|
||||||
Email string `json:"email" gorm:"unique"`
|
Email *string `json:"email" gorm:"unique"`
|
||||||
Role string `json:"role" gorm:"default:user;not null;index:users_role_idx;type:varchar(8)"`
|
Role string `json:"role" gorm:"default:user;not null;index:users_role_idx;type:varchar(8)"`
|
||||||
Image string `json:"image" gorm:"type:varchar(255)"`
|
Image string `json:"image" gorm:"type:varchar(255)"`
|
||||||
|
|
||||||
Teams []*TeamMembers `json:"teams" gorm:"foreignKey:UserID"`
|
Teams []*TeamMembers `json:"teams" gorm:"foreignKey:UserID"`
|
||||||
Accounts []*UserAccount `json:"accounts" gorm:"foreignKey:UserID"`
|
Accounts []*UserAccount `json:"accounts" gorm:"foreignKey:UserID"`
|
||||||
|
@ -4,8 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"rul.sh/vaulterm/server/lib"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetDataPath(resolveFile string) string {
|
func GetDataPath(resolveFile string) string {
|
||||||
@ -35,7 +33,7 @@ func CheckAndCreateEnvFile() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// File doesn't exist, so create it
|
// File doesn't exist, so create it
|
||||||
randomKey, err := lib.GenerateRandomKey()
|
randomKey, err := GenerateRandomKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package lib
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/aes"
|
"crypto/aes"
|
5
server/utils/string.go
Normal file
5
server/utils/string.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
func StringPtr(s string) *string {
|
||||||
|
return &s
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user