Compare commits
6 Commits
8278b74ae8
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| ff1c51c723 | |||
| bfa9f9dd79 | |||
| 91585fdb0a | |||
| cd42a6b0bf | |||
| 35a8b14af2 | |||
| 0d3a68997a |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@
|
||||
coverage
|
||||
.notes
|
||||
uploads
|
||||
bin
|
||||
59
Makefile
Normal file
59
Makefile
Normal file
@@ -0,0 +1,59 @@
|
||||
COVERAGE_DIR := coverage
|
||||
BIN_DIR := ./bin
|
||||
MAIN := ./cmd/http/main.go
|
||||
APP_NAME := prosody_password
|
||||
|
||||
lint:
|
||||
golangci-lint run ./...
|
||||
goreportcard:
|
||||
goreportcard-cli -v
|
||||
test:
|
||||
go test ./...
|
||||
test-coverage:
|
||||
rm -rf ${COVERAGE_DIR}
|
||||
mkdir ${COVERAGE_DIR}
|
||||
go test -v -coverprofile ${COVERAGE_DIR}/cover.out ./...
|
||||
go tool cover -html ${COVERAGE_DIR}/cover.out -o ${COVERAGE_DIR}/cover.html
|
||||
|
||||
|
||||
.PHONY: local_run
|
||||
local_run:
|
||||
go run ./cmd/main.go --dir "$(DIR)" --bucket "$(BUCKET)"
|
||||
|
||||
.PHONY: build_linux_amd64
|
||||
build_linux_amd64:
|
||||
@mkdir -p $(BIN_DIR)
|
||||
GOOS=linux GOARCH=amd64 go build -o $(BIN_DIR)/$(APP_NAME)_linux_amd64 $(MAIN)
|
||||
|
||||
.PHONY: build_linux_arm64
|
||||
build_linux_arm64:
|
||||
@mkdir -p $(BIN_DIR)
|
||||
GOOS=linux GOARCH=arm64 go build -o $(BIN_DIR)/$(APP_NAME)_linux_arm64 $(MAIN)
|
||||
|
||||
.PHONY: build_windows_amd64
|
||||
build_windows_amd64:
|
||||
@mkdir -p $(BIN_DIR)
|
||||
GOOS=windows GOARCH=amd64 go build -o $(BIN_DIR)/$(APP_NAME)_windows_amd64.exe $(MAIN)
|
||||
|
||||
.PHONY: build_windows_386
|
||||
build_windows_386:
|
||||
@mkdir -p $(BIN_DIR)
|
||||
GOOS=windows GOARCH=386 go build -o $(BIN_DIR)/$(APP_NAME)_windows_386.exe $(MAIN)
|
||||
|
||||
.PHONY: build_mac_amd64
|
||||
build_mac_amd64:
|
||||
@mkdir -p $(BIN_DIR)
|
||||
GOOS=darwin GOARCH=amd64 go build -o $(BIN_DIR)/$(APP_NAME)_mac_amd64 $(MAIN)
|
||||
|
||||
.PHONY: build_mac_arm64
|
||||
build_mac_arm64:
|
||||
@mkdir -p $(BIN_DIR)
|
||||
GOOS=darwin GOARCH=arm64 go build -o $(BIN_DIR)/$(APP_NAME)_mac_arm64 $(MAIN)
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf $(BIN_DIR)
|
||||
|
||||
.PHONY: rebuild
|
||||
#rebuild: clean build_linux_amd64 build_linux_arm64 build_windows_amd64 build_windows_386 build_mac_amd64 build_mac_arm64
|
||||
rebuild: clean build_linux_amd64 build_windows_amd64 build_windows_386 build_mac_amd64
|
||||
73
README.md
Normal file
73
README.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Prosody Password Manager
|
||||
This project provides a web interface to change the password for XMPP accounts managed by Prosody. It interfaces with the Prosody server to securely handle password changes.
|
||||
|
||||
## Project Structure
|
||||
```bash
|
||||
.
|
||||
├── cmd
|
||||
│ └── http
|
||||
│ ├── main.go
|
||||
│ └── views
|
||||
│ ├── error.hbs
|
||||
│ ├── index.hbs
|
||||
│ ├── styles.hbs
|
||||
│ └── success.hbs
|
||||
├── go.mod
|
||||
├── go.sum
|
||||
├── internal
|
||||
│ ├── api
|
||||
│ │ ├── handler
|
||||
│ │ │ ├── helper.go
|
||||
│ │ │ └── prosody_hdl.go
|
||||
│ │ └── server.go
|
||||
│ └── services
|
||||
│ ├── fail2ban
|
||||
│ │ └── fail.go
|
||||
│ └── prosody
|
||||
│ ├── account.go
|
||||
│ ├── change_password.go
|
||||
│ ├── change_password_test.go
|
||||
│ └── prosody.go
|
||||
├── kit
|
||||
│ ├── config
|
||||
│ │ └── config.go
|
||||
│ └── path.go
|
||||
└── LICENSE
|
||||
```
|
||||
|
||||
## Key Files
|
||||
|
||||
- **logic** to change the password in the Prosody server. It interfaces with the Prosody server's command-line tools and verifies the current password before making any changes.
|
||||
|
||||
- **prosody.go**: Provides utility functions related to the Prosody server, including constructing paths to account data files.
|
||||
|
||||
- **account.go**: Contains utility functions to load account details from Prosody's data files.
|
||||
|
||||
- **server.go**: Sets up the web server, routes, and middleware for the application.
|
||||
|
||||
- **main.go**: The entry point of the application. It initializes the services and starts the web server.
|
||||
|
||||
## Requirements
|
||||
|
||||
- **Prosody Server**: Ensure that the Prosody server is installed and running on your machine. This application interfaces with Prosody's command-line tools to manage XMPP accounts.
|
||||
|
||||
- **Environment Variables**: The application requires certain environment variables to be set. These can be provided directly or through a **.env** file. The required variables are:
|
||||
- **DOMAIN**: The domain for the Prosody server (e.g., **xmpp.example.com**).
|
||||
- **API_PORT** (optional): The port on which the web server will run. Defaults to **8080** if not provided.
|
||||
- **VIEWS** (optional): The path to the directory containing view templates. Defaults to **./views** if not provided.
|
||||
|
||||
## Setup & Running
|
||||
|
||||
1. Ensure you have Go installed on your machine.
|
||||
2. Clone the repository.
|
||||
3. Navigate to the project directory.
|
||||
4. Run the application using:
|
||||
|
||||
```bash
|
||||
go run cmd/http/main.go
|
||||
```
|
||||
|
||||
Visit **http://localhost:<API_PORT>** in your browser to access the password change interface.
|
||||
|
||||
## Contributing
|
||||
If you'd like to contribute to this project, please fork the repository and submit a pull request.
|
||||
@@ -36,7 +36,9 @@ func main() {
|
||||
|
||||
log.Println("on shutdown")
|
||||
if restServer != nil {
|
||||
restServer.Shutdown()
|
||||
if err := restServer.Shutdown(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
log.Println("gracefully shutdown")
|
||||
|
||||
|
||||
2
go.mod
2
go.mod
@@ -1,6 +1,6 @@
|
||||
module gitea.urkob.com/urko/prosody-password
|
||||
|
||||
go 1.20
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
gitea.urkob.com/urko/go-root-dir v0.0.0-20230311113851-2f6d4355888a
|
||||
|
||||
@@ -2,6 +2,7 @@ package handler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"gitea.urkob.com/urko/prosody-password/internal/services/fail2ban"
|
||||
"gitea.urkob.com/urko/prosody-password/internal/services/prosody"
|
||||
@@ -31,12 +32,14 @@ func (handler ProsodyHandler) Post(c *fiber.Ctx) error {
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return RenderError(c, fmt.Errorf(" c.BodyParser(&req): %w", err), defaultErrMessage)
|
||||
}
|
||||
log.Println("request ip", c.IP())
|
||||
log.Println("c.IPs()", c.IPs())
|
||||
req.CurrentPassword = c.FormValue("current_password")
|
||||
req.NewPassword = c.FormValue("new_password")
|
||||
if err := handler.prosodyService.ChangePassword(req.User, req.CurrentPassword, req.NewPassword); err != nil {
|
||||
// for _, ip := range c.IPs() {
|
||||
// handler.fail2banSrv.FailedAttempt(ip)
|
||||
// }
|
||||
for _, ip := range c.IPs() {
|
||||
handler.fail2banSrv.FailedAttempt(ip)
|
||||
}
|
||||
return RenderError(c, fmt.Errorf("ChangePassword: %w", err), defaultErrMessage)
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,8 @@ func (s *RestServer) Start(apiPort, views string) error {
|
||||
engine := handlebars.New(views, ".hbs")
|
||||
s.app = fiber.New(fiber.Config{
|
||||
Views: engine,
|
||||
ProxyHeader: "X-Forwarded-For",
|
||||
EnableIPValidation: true,
|
||||
})
|
||||
|
||||
s.app.Use(limiter.New(limiter.Config{
|
||||
@@ -47,7 +49,6 @@ func (s *RestServer) Start(apiPort, views string) error {
|
||||
AllowHeaders: "Origin, Accept, Content-Type, X-CSRF-Token, Authorization",
|
||||
ExposeHeaders: "Origin",
|
||||
}))
|
||||
|
||||
s.loadViews()
|
||||
|
||||
prosodyHdl := handler.NewProsodyHandler(s.prosodyService, s.fail2banSrv)
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
)
|
||||
|
||||
type account struct {
|
||||
User string
|
||||
Salt string `prosody:"salt"`
|
||||
StoredKey string `prosody:"stored_key"`
|
||||
IterationCount string `prosody:"iteration_count"`
|
||||
@@ -47,7 +48,9 @@ func (p *Prosody) loadAccount(username string) (*account, error) {
|
||||
}
|
||||
}
|
||||
|
||||
acc := &account{}
|
||||
acc := &account{
|
||||
User: username,
|
||||
}
|
||||
acc.unmarshal(mapValues)
|
||||
return acc, nil
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ func (p *Prosody) ChangePassword(user string, currentPwd string, newPwd string)
|
||||
return errors.New("password is incorrect")
|
||||
}
|
||||
|
||||
cmd := exec.Command("/usr/bin/prosodyctl", "passwd", user+"@"+p.plainDomain)
|
||||
cmd := exec.Command("/usr/bin/prosodyctl", "passwd", acc.User+"@"+p.plainDomain)
|
||||
// Create a pipe to write to the process's standard input.
|
||||
stdin, err := cmd.StdinPipe()
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user