material_manage_system/internal/repository/organization_access.go

49 lines
1.9 KiB
Go

package repository
import (
"database/sql"
"github.com/wmms/wmms/internal/model"
"github.com/wmms/wmms/pkg/database"
)
// Authorization is evaluated from current database grants and enabled roles on
// every call, so role changes and grant revocation do not wait for JWT expiry.
func (r *OrganizationRepository) ListAccessible(userID int64) (*model.OrganizationAccess, error) {
rows, err := database.DB.Query(`SELECT o.id,o.code,o.name,o.status,o.default_timezone,o.created_at,o.updated_at,
COALESCE(g.is_default,0) FROM organizations o
LEFT JOIN user_organizations g ON g.organization_id=o.id AND g.user_id=?
WHERE o.status='active' AND (g.user_id IS NOT NULL OR EXISTS(
SELECT 1 FROM user_roles ur JOIN roles r ON r.id=ur.role_id
WHERE ur.user_id=? AND r.code='super_admin' AND r.enabled=1)) ORDER BY o.id`, userID, userID)
if err != nil {
return nil, err
}
defer rows.Close()
access := &model.OrganizationAccess{Organizations: make([]model.Organization, 0)}
for rows.Next() {
var item model.Organization
var isDefault bool
if err := rows.Scan(&item.ID, &item.Code, &item.Name, &item.Status, &item.DefaultTimezone, &item.CreatedAt, &item.UpdatedAt, &isDefault); err != nil {
return nil, err
}
access.Organizations = append(access.Organizations, item)
if isDefault {
id := item.ID
access.DefaultOrganizationID = &id
}
}
return access, rows.Err()
}
func (r *OrganizationRepository) CanAccess(userID, organizationID int64) (bool, error) {
var allowed bool
err := database.DB.QueryRow(`SELECT EXISTS(SELECT 1 FROM organizations o WHERE o.id=? AND o.status='active'
AND (EXISTS(SELECT 1 FROM user_organizations g WHERE g.user_id=? AND g.organization_id=o.id)
OR EXISTS(SELECT 1 FROM user_roles ur JOIN roles r ON r.id=ur.role_id
WHERE ur.user_id=? AND r.code='super_admin' AND r.enabled=1)))`, organizationID, userID, userID).Scan(&allowed)
if err == sql.ErrNoRows {
return false, nil
}
return allowed, err
}