mirror of
https://github.com/snipe/snipe-it.git
synced 2024-12-24 05:04:07 -08:00
Merge branch 'develop'
This commit is contained in:
commit
792a31cc7f
|
@ -2146,6 +2146,78 @@
|
|||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "raelldottin",
|
||||
"name": "Raell Dottin",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/317015?v=4",
|
||||
"profile": "https://github.com/raelldottin",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "misilot",
|
||||
"name": "Tom Misilo",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/1446856?v=4",
|
||||
"profile": "https://github.com/misilot",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "JuustoMestari",
|
||||
"name": "David Davenne",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/4496300?v=4",
|
||||
"profile": "http://david.davenne.be",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ocelotsloth",
|
||||
"name": "Mark Stenglein",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/9255772?v=4",
|
||||
"profile": "https://markstenglein.com",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "ajsy",
|
||||
"name": "ajsy",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/35658596?v=4",
|
||||
"profile": "https://github.com/ajsy",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "t3easy",
|
||||
"name": "Jan Kiesewetter",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/3628035?v=4",
|
||||
"profile": "https://github.com/t3easy",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Tetrachloromethane250",
|
||||
"name": "Tetrachloromethane250",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/79449630?v=4",
|
||||
"profile": "https://github.com/Tetrachloromethane250",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "kajes",
|
||||
"name": "Lars Kajes",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/22004482?v=4",
|
||||
"profile": "https://www.kajes.se/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -144,6 +144,11 @@ APP_LOG=single
|
|||
APP_LOG_MAX_FILES=10
|
||||
APP_LOCKED=false
|
||||
APP_CIPHER=AES-256-CBC
|
||||
APP_FORCE_TLS=false
|
||||
GOOGLE_MAPS_API=
|
||||
LDAP_MEM_LIM=500M
|
||||
LDAP_TIME_LIM=600
|
||||
IMPORT_TIME_LIMIT=600
|
||||
IMPORT_MEMORY_LIMIT=500M
|
||||
REPORT_TIME_LIMIT=12000
|
||||
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -52,6 +52,8 @@ tests/_support/_generated/*
|
|||
*.cache
|
||||
|
||||
.vagrant
|
||||
*.log
|
||||
*.retry
|
||||
|
||||
\.php_cs\.dist
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ RUN \
|
|||
&& mkdir -p "/var/lib/snipeit/dumps" && rm -r "/var/www/html/storage/app/backups" && ln -fs "/var/lib/snipeit/dumps" "/var/www/html/storage/app/backups" \
|
||||
&& mkdir -p "/var/lib/snipeit/keys" && ln -fs "/var/lib/snipeit/keys/oauth-private.key" "/var/www/html/storage/oauth-private.key" \
|
||||
&& ln -fs "/var/lib/snipeit/keys/oauth-public.key" "/var/www/html/storage/oauth-public.key" \
|
||||
&& chown -h "/var/www/html/storage/*.key"
|
||||
&& chown -R apache "/var/lib/snipeit"
|
||||
|
||||
# Install composer
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
![Build Status](https://app.chipperci.com/projects/0e5f8979-31eb-4ee6-9abf-050b76ab0383/status/master) [![Crowdin](https://d322cqt584bo4o.cloudfront.net/snipe-it/localized.svg)](https://crowdin.com/project/snipe-it) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/snipe/snipe-it?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Docker Pulls](https://img.shields.io/docker/pulls/snipe/snipe-it.svg)](https://hub.docker.com/r/snipe/snipe-it/) [![Twitter Follow](https://img.shields.io/twitter/follow/snipeitapp.svg?style=social)](https://twitter.com/snipeitapp) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/553ce52037fc43ea99149785afcfe641)](https://www.codacy.com/app/snipe/snipe-it?utm_source=github.com&utm_medium=referral&utm_content=snipe/snipe-it&utm_campaign=Badge_Grade)
|
||||
[![All Contributors](https://img.shields.io/badge/all_contributors-235-orange.svg?style=flat-square)](#contributors)
|
||||
[![All Contributors](https://img.shields.io/badge/all_contributors-243-orange.svg?style=flat-square)](#contributors)
|
||||
|
||||
## Snipe-IT - Open Source Asset Management System
|
||||
|
||||
|
@ -122,7 +122,8 @@ Thanks goes to all of these wonderful people ([emoji key](https://github.com/ken
|
|||
| [<img src="https://avatars0.githubusercontent.com/u/1255375?v=4" width="110px;"/><br /><sub>Peter Upfold</sub>](https://peter.upfold.org.uk/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PeterUpfold "Code") | [<img src="https://avatars2.githubusercontent.com/u/961717?v=4" width="110px;"/><br /><sub>Jared Biel</sub>](https://github.com/jbiel)<br />[💻](https://github.com/snipe/snipe-it/commits?author=jbiel "Code") | [<img src="https://avatars1.githubusercontent.com/u/1733625?v=4" width="110px;"/><br /><sub>Dampfklon</sub>](https://github.com/dampfklon)<br />[💻](https://github.com/snipe/snipe-it/commits?author=dampfklon "Code") | [<img src="https://avatars2.githubusercontent.com/u/52973156?v=4" width="110px;"/><br /><sub>Charles Hamilton</sub>](https://communityclosing.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=chamilton-ccn "Code") | [<img src="https://avatars.githubusercontent.com/u/551789?v=4" width="110px;"/><br /><sub>Giuseppe Iannello</sub>](https://github.com/giannello)<br />[💻](https://github.com/snipe/snipe-it/commits?author=giannello "Code") | [<img src="https://avatars.githubusercontent.com/u/3691490?v=4" width="110px;"/><br /><sub>Peter Dave Hello</sub>](https://www.peterdavehello.org/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PeterDaveHello "Code") | [<img src="https://avatars.githubusercontent.com/u/6106332?v=4" width="110px;"/><br /><sub>sigmoidal</sub>](https://github.com/sigmoidal)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sigmoidal "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/2082554?v=4" width="110px;"/><br /><sub>Vincent Lainé</sub>](https://github.com/phenixdotnet)<br />[💻](https://github.com/snipe/snipe-it/commits?author=phenixdotnet "Code") | [<img src="https://avatars.githubusercontent.com/u/1943040?v=4" width="110px;"/><br /><sub>Lucas Pleß</sub>](http://www.lucas-pless.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=derlucas "Code") | [<img src="https://avatars.githubusercontent.com/u/472804?v=4" width="110px;"/><br /><sub>Ian Littman</sub>](http://twitter.com/iansltx)<br />[💻](https://github.com/snipe/snipe-it/commits?author=iansltx "Code") | [<img src="https://avatars.githubusercontent.com/u/3519029?v=4" width="110px;"/><br /><sub>João Paulo</sub>](https://github.com/PauloLuna)<br />[💻](https://github.com/snipe/snipe-it/commits?author=PauloLuna "Code") | [<img src="https://avatars.githubusercontent.com/u/70443365?v=4" width="110px;"/><br /><sub>ThoBur</sub>](https://github.com/ThoBur)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ThoBur "Code") | [<img src="https://avatars.githubusercontent.com/u/1972329?v=4" width="110px;"/><br /><sub>Alexander Chibrikin</sub>](http://phpprofi.ru/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=alek13 "Code") | [<img src="https://avatars.githubusercontent.com/u/438332?v=4" width="110px;"/><br /><sub>Anthony Winstanley</sub>](https://github.com/winstan)<br />[💻](https://github.com/snipe/snipe-it/commits?author=winstan "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/3075214?v=4" width="110px;"/><br /><sub>Folke</sub>](https://github.com/fashberg)<br />[💻](https://github.com/snipe/snipe-it/commits?author=fashberg "Code") | [<img src="https://avatars.githubusercontent.com/u/1351571?v=4" width="110px;"/><br /><sub>Bennett Blodinger</sub>](https://github.com/benwa)<br />[💻](https://github.com/snipe/snipe-it/commits?author=benwa "Code") | [<img src="https://avatars.githubusercontent.com/u/2974631?v=4" width="110px;"/><br /><sub>NMC</sub>](https://nmc.dev)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ncareau "Code") | [<img src="https://avatars.githubusercontent.com/u/52182449?v=4" width="110px;"/><br /><sub>andres-baller</sub>](https://github.com/andres-baller)<br />[💻](https://github.com/snipe/snipe-it/commits?author=andres-baller "Code") | [<img src="https://avatars.githubusercontent.com/u/67109348?v=4" width="110px;"/><br /><sub>sean-borg</sub>](https://github.com/sean-borg)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sean-borg "Code") | [<img src="https://avatars.githubusercontent.com/u/32170051?v=4" width="110px;"/><br /><sub>EDVLeer</sub>](https://github.com/EDVLeer)<br />[💻](https://github.com/snipe/snipe-it/commits?author=EDVLeer "Code") | [<img src="https://avatars.githubusercontent.com/u/23075196?v=4" width="110px;"/><br /><sub>Kurokat</sub>](https://github.com/Kurokat)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Kurokat "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/915514?v=4" width="110px;"/><br /><sub>Kevin Köllmann</sub>](https://www.kevinkoellmann.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=koelle25 "Code") | [<img src="https://avatars.githubusercontent.com/u/49025941?v=4" width="110px;"/><br /><sub>sw-mreyes</sub>](https://github.com/sw-mreyes)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sw-mreyes "Code") | [<img src="https://avatars.githubusercontent.com/u/70129?v=4" width="110px;"/><br /><sub>Joel Pittet</sub>](https://pittet.ca)<br />[💻](https://github.com/snipe/snipe-it/commits?author=joelpittet "Code") | [<img src="https://avatars.githubusercontent.com/u/792695?v=4" width="110px;"/><br /><sub>Eli Young</sub>](https://elyscape.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=elyscape "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/915514?v=4" width="110px;"/><br /><sub>Kevin Köllmann</sub>](https://www.kevinkoellmann.de)<br />[💻](https://github.com/snipe/snipe-it/commits?author=koelle25 "Code") | [<img src="https://avatars.githubusercontent.com/u/49025941?v=4" width="110px;"/><br /><sub>sw-mreyes</sub>](https://github.com/sw-mreyes)<br />[💻](https://github.com/snipe/snipe-it/commits?author=sw-mreyes "Code") | [<img src="https://avatars.githubusercontent.com/u/70129?v=4" width="110px;"/><br /><sub>Joel Pittet</sub>](https://pittet.ca)<br />[💻](https://github.com/snipe/snipe-it/commits?author=joelpittet "Code") | [<img src="https://avatars.githubusercontent.com/u/792695?v=4" width="110px;"/><br /><sub>Eli Young</sub>](https://elyscape.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=elyscape "Code") | [<img src="https://avatars.githubusercontent.com/u/317015?v=4" width="110px;"/><br /><sub>Raell Dottin</sub>](https://github.com/raelldottin)<br />[💻](https://github.com/snipe/snipe-it/commits?author=raelldottin "Code") | [<img src="https://avatars.githubusercontent.com/u/1446856?v=4" width="110px;"/><br /><sub>Tom Misilo</sub>](https://github.com/misilot)<br />[💻](https://github.com/snipe/snipe-it/commits?author=misilot "Code") | [<img src="https://avatars.githubusercontent.com/u/4496300?v=4" width="110px;"/><br /><sub>David Davenne</sub>](http://david.davenne.be)<br />[💻](https://github.com/snipe/snipe-it/commits?author=JuustoMestari "Code") |
|
||||
| [<img src="https://avatars.githubusercontent.com/u/9255772?v=4" width="110px;"/><br /><sub>Mark Stenglein</sub>](https://markstenglein.com)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ocelotsloth "Code") | [<img src="https://avatars.githubusercontent.com/u/35658596?v=4" width="110px;"/><br /><sub>ajsy</sub>](https://github.com/ajsy)<br />[💻](https://github.com/snipe/snipe-it/commits?author=ajsy "Code") | [<img src="https://avatars.githubusercontent.com/u/3628035?v=4" width="110px;"/><br /><sub>Jan Kiesewetter</sub>](https://github.com/t3easy)<br />[💻](https://github.com/snipe/snipe-it/commits?author=t3easy "Code") | [<img src="https://avatars.githubusercontent.com/u/79449630?v=4" width="110px;"/><br /><sub>Tetrachloromethane250</sub>](https://github.com/Tetrachloromethane250)<br />[💻](https://github.com/snipe/snipe-it/commits?author=Tetrachloromethane250 "Code") | [<img src="https://avatars.githubusercontent.com/u/22004482?v=4" width="110px;"/><br /><sub>Lars Kajes</sub>](https://www.kajes.se/)<br />[💻](https://github.com/snipe/snipe-it/commits?author=kajes "Code") |
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
|
||||
This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome!
|
||||
|
|
27
Vagrantfile
vendored
27
Vagrantfile
vendored
|
@ -8,25 +8,34 @@ Vagrant.configure("2") do |config|
|
|||
config.vm.define "bionic" do |bionic|
|
||||
bionic.vm.box = "ubuntu/bionic64"
|
||||
bionic.vm.hostname = 'bionic'
|
||||
bionic.vm.network "public_network", bridge: NETWORK_BRIDGE
|
||||
bionic.vm.provision :shell, :inline => "wget #{SNIPEIT_SH_URL}"
|
||||
bionic.vm.provision :shell, :inline => "chmod 755 snipeit.sh"
|
||||
bionic.vm.network "forwarded_port", guest: 80, host: 8080
|
||||
bionic.vm.synced_folder ".", "/vagrant", :owner => 'www-data',
|
||||
:group => 'vagrant', :mount_options => ['dmode=775', 'fmode=775']
|
||||
bionic.vm.provision "ansible_local" do |ansible|
|
||||
ansible.playbook = "ansible/ubuntu/vagrant_playbook.yml"
|
||||
end
|
||||
end
|
||||
|
||||
config.vm.define "xenial" do |xenial|
|
||||
xenial.vm.box = "ubuntu/xenial64"
|
||||
xenial.vm.hostname = 'xenial'
|
||||
xenial.vm.network "public_network", bridge: NETWORK_BRIDGE
|
||||
xenial.vm.provision :shell, :inline => "wget #{SNIPEIT_SH_URL}"
|
||||
xenial.vm.provision :shell, :inline => "chmod 755 snipeit.sh"
|
||||
xenial.vm.network "forwarded_port", guest: 80, host: 8080
|
||||
xenial.vm.synced_folder ".", "/vagrant", :owner => 'www-data',
|
||||
:group => 'vagrant', :mount_options => ['dmode=775', 'fmode=775']
|
||||
xenial.vm.provision "ansible_local" do |ansible|
|
||||
ansible.playbook = "ansible/ubuntu/vagrant_playbook.yml"
|
||||
end
|
||||
end
|
||||
|
||||
config.vm.define "trusty" do |trusty|
|
||||
trusty.vm.box = "ubuntu/trusty32"
|
||||
trusty.vm.hostname = 'trusty'
|
||||
trusty.vm.network "public_network", bridge: NETWORK_BRIDGE
|
||||
trusty.vm.provision :shell, :inline => "wget #{SNIPEIT_SH_URL}"
|
||||
trusty.vm.provision :shell, :inline => "chmod 755 snipeit.sh"
|
||||
trusty.vm.network "forwarded_port", guest: 80, host: 8080
|
||||
trusty.vm.synced_folder ".", "/vagrant", :owner => 'www-data',
|
||||
:group => 'vagrant', :mount_options => ['dmode=775', 'fmode=775']
|
||||
trusty.vm.provision "ansible_local" do |ansible|
|
||||
ansible.playbook = "ansible/ubuntu/vagrant_playbook.yml"
|
||||
end
|
||||
end
|
||||
|
||||
config.vm.define "centos7" do |centos7|
|
||||
|
|
10
ansible/ubuntu/apachevirtualhost.conf.j2
Executable file
10
ansible/ubuntu/apachevirtualhost.conf.j2
Executable file
|
@ -0,0 +1,10 @@
|
|||
<VirtualHost *:80>
|
||||
<Directory {{ app_path }}/public>
|
||||
Allow From All
|
||||
AllowOverride All
|
||||
Options -Indexes
|
||||
</Directory>
|
||||
|
||||
DocumentRoot {{ app_path }}/public
|
||||
ServerName {{ fqdn }}
|
||||
</VirtualHost>
|
226
ansible/ubuntu/vagrant_playbook.yml
Executable file
226
ansible/ubuntu/vagrant_playbook.yml
Executable file
|
@ -0,0 +1,226 @@
|
|||
---
|
||||
- name: Set up local server
|
||||
hosts: all
|
||||
remote_user: vagrant
|
||||
become_user: root
|
||||
become_method: sudo
|
||||
vars:
|
||||
app_path: "/var/www/snipeit"
|
||||
fqdn: "localhost"
|
||||
tasks:
|
||||
- name: Update and upgrade existing apt packages
|
||||
become: true
|
||||
apt:
|
||||
upgrade: yes
|
||||
update_cache: yes
|
||||
- name: Install Utilities
|
||||
become: true
|
||||
apt:
|
||||
name: "{{ packages }}"
|
||||
state: present
|
||||
vars:
|
||||
packages:
|
||||
- nano
|
||||
- vim
|
||||
- name: Installing Apache httpd, PHP, MariaDB and other requirements.
|
||||
become: true
|
||||
apt:
|
||||
name: "{{ packages }}"
|
||||
state: present
|
||||
vars:
|
||||
packages:
|
||||
- mariadb-client
|
||||
- php
|
||||
- php-curl
|
||||
- php-mysql
|
||||
- php-gd
|
||||
- php-ldap
|
||||
- php-zip
|
||||
- php-mbstring
|
||||
- php-xml
|
||||
- php-bcmath
|
||||
- curl
|
||||
- git
|
||||
- unzip
|
||||
- python-pymysql
|
||||
#
|
||||
# Install the lastest version of composer
|
||||
#
|
||||
- name: Composer check
|
||||
stat:
|
||||
path: /usr/local/bin/composer
|
||||
register: composer_exits
|
||||
- name: Install Composer
|
||||
shell: |
|
||||
EXPECTED_SIGNATURE=$(wget -q -O - https://composer.github.io/installer.sig)
|
||||
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
||||
ACTUAL_SIGNATURE=$(php -r "echo hash_file('SHA384', 'composer-setup.php');")
|
||||
|
||||
if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]
|
||||
then
|
||||
>&2 echo 'ERROR: Invalid installer signature'
|
||||
rm composer-setup.php
|
||||
exit 1
|
||||
fi
|
||||
|
||||
php composer-setup.php --quiet
|
||||
RESULT=$?
|
||||
rm composer-setup.php
|
||||
mv composer.phar /usr/local/bin/composer
|
||||
exit $RESULT
|
||||
when: not composer_exits.stat.exists
|
||||
args:
|
||||
creates: /usr/local/bin/composer
|
||||
become: true
|
||||
#
|
||||
# Install and Configure MariaDB
|
||||
#
|
||||
- name: Install MariaDB
|
||||
become: true
|
||||
apt:
|
||||
name: mariadb-server
|
||||
state: present
|
||||
register: sql_server
|
||||
- name: Start and Enable MySQL server
|
||||
become: true
|
||||
systemd:
|
||||
state: started
|
||||
enabled: yes
|
||||
name: mariadb
|
||||
- name: Create Vagrant mysql password
|
||||
become: true
|
||||
mysql_user:
|
||||
name: vagrant
|
||||
password: vagrant
|
||||
login_unix_socket: /var/run/mysqld/mysqld.sock
|
||||
priv: "*.*:ALL"
|
||||
state: present
|
||||
- name: Enable remote mysql
|
||||
replace:
|
||||
path: /etc/mysql/mariadb.conf.d/50-server.cnf
|
||||
regexp: "127.0.0.1"
|
||||
replace: "0.0.0.0"
|
||||
become: true
|
||||
notify:
|
||||
- restart mysql
|
||||
- name: Create snipeit database
|
||||
become: true
|
||||
mysql_db:
|
||||
name: snipeit
|
||||
state: present
|
||||
login_unix_socket: /var/run/mysqld/mysqld.sock
|
||||
#
|
||||
# Install Apache Web Server
|
||||
#
|
||||
- name: Install Apache 2.4
|
||||
apt:
|
||||
name: "{{ packages }}"
|
||||
state: present
|
||||
vars:
|
||||
packages:
|
||||
- apache2
|
||||
- libapache2-mod-php
|
||||
become: true
|
||||
register: apache2_server
|
||||
- name: Start and Enable Apache2 Server
|
||||
become: true
|
||||
systemd:
|
||||
name: apache2
|
||||
state: started
|
||||
enabled: yes
|
||||
#- name: Disable Apache modules
|
||||
# become: true
|
||||
# apache2_module:
|
||||
# state: absent
|
||||
# name: "{{ item }}"
|
||||
# with_items:
|
||||
# #- mpm_prefork
|
||||
# notify:
|
||||
# - restart apache2
|
||||
- name: Enable Apache modules
|
||||
become: true
|
||||
apache2_module:
|
||||
state: present
|
||||
name: "{{ item }}"
|
||||
with_items:
|
||||
- rewrite
|
||||
- vhost_alias
|
||||
- deflate
|
||||
- expires
|
||||
- proxy_fcgi
|
||||
- proxy
|
||||
notify:
|
||||
- restart apache2
|
||||
- name: Install Apache VirtualHost File
|
||||
become: true
|
||||
template:
|
||||
src: apachevirtualhost.conf.j2
|
||||
dest: "/etc/apache2/sites-available/snipeit.conf"
|
||||
- name: Enable VirtualHost
|
||||
become: true
|
||||
command: a2ensite snipeit
|
||||
args:
|
||||
creates: /etc/apache2/sites-enabled/snipeit.conf
|
||||
notify:
|
||||
- restart apache2
|
||||
- name: Map apache dir to local folder
|
||||
become: true
|
||||
file:
|
||||
src: /vagrant
|
||||
dest: "{{ app_path }}"
|
||||
state: link
|
||||
notify:
|
||||
- restart apache2
|
||||
#
|
||||
# Install dependencies from composer
|
||||
#
|
||||
- name: Install dependencies from composer
|
||||
composer:
|
||||
command: install
|
||||
working_dir: "{{ app_path }}"
|
||||
notify:
|
||||
- restart apache2
|
||||
#
|
||||
# Configure .env file
|
||||
#
|
||||
- name: Copy .env file
|
||||
copy:
|
||||
src: "{{ app_path }}/.env.example"
|
||||
dest: "{{ app_path }}/.env"
|
||||
- name: Configure .env file
|
||||
lineinfile:
|
||||
path: "{{ app_path }}/.env"
|
||||
regexp: "{{ item.regexp }}"
|
||||
line: "{{ item.line }}"
|
||||
with_items:
|
||||
- { regexp: '^DB_HOST=', line: 'DB_HOST=127.0.0.1'}
|
||||
- { regexp: '^DB_DATABASE=', line: 'DB_DATABASE=snipeit' }
|
||||
- { regexp: '^DB_USERNAME=', line: 'DB_USERNAME=vagrant' }
|
||||
- { regexp: '^DB_PASSWORD=', line: 'DB_PASSWORD=vagrant' }
|
||||
- { regexp: '^APP_URL=', line: "APP_URL=http://{{ fqdn }}" }
|
||||
- { regexp: '^APP_ENV=', line: "APP_ENV=development" }
|
||||
- { regexp: '^APP_DEBUG=', line: "APP_ENV=true" }
|
||||
- name: Generate application key
|
||||
shell: "php {{ app_path }}/artisan key:generate --force"
|
||||
- name: Artisan Migrate
|
||||
shell: "php {{ app_path }}/artisan migrate --force"
|
||||
#
|
||||
# Create Cron Job
|
||||
#
|
||||
- name: Create scheduler cron job
|
||||
become: true
|
||||
cron:
|
||||
name: "Snipe-IT Artisan Scheduler"
|
||||
job: "/usr/bin/php {{ app_path }}/artisan schedule:run"
|
||||
handlers:
|
||||
- name: restart apache2
|
||||
become: true
|
||||
systemd:
|
||||
name: apache2
|
||||
state: restarted
|
||||
- name: restart mysql
|
||||
become: true
|
||||
systemd:
|
||||
name: mysql
|
||||
state: restarted
|
||||
|
|
@ -51,6 +51,9 @@ class LdapSync extends Command
|
|||
$ldap_result_active_flag = Setting::getSettings()->ldap_active_flag_field;
|
||||
$ldap_result_emp_num = Setting::getSettings()->ldap_emp_num;
|
||||
$ldap_result_email = Setting::getSettings()->ldap_email;
|
||||
$ldap_result_phone = Setting::getSettings()->ldap_phone_field;
|
||||
$ldap_result_jobtitle = Setting::getSettings()->ldap_jobtitle;
|
||||
$ldap_result_country = Setting::getSettings()->ldap_country;
|
||||
|
||||
try {
|
||||
$ldapconn = Ldap::connectToLdap();
|
||||
|
@ -175,6 +178,9 @@ class LdapSync extends Command
|
|||
$item["email"] = isset($results[$i][$ldap_result_email][0]) ? $results[$i][$ldap_result_email][0] : "" ;
|
||||
$item["ldap_location_override"] = isset($results[$i]["ldap_location_override"]) ? $results[$i]["ldap_location_override"]:"";
|
||||
$item["location_id"] = isset($results[$i]["location_id"]) ? $results[$i]["location_id"]:"";
|
||||
$item["telephone"] = isset($results[$i][$ldap_result_phone][0]) ? $results[$i][$ldap_result_phone][0] : "";
|
||||
$item["jobtitle"] = isset($results[$i][$ldap_result_jobtitle][0]) ? $results[$i][$ldap_result_jobtitle][0] : "";
|
||||
$item["country"] = isset($results[$i][$ldap_result_country][0]) ? $results[$i][$ldap_result_country][0] : "";
|
||||
|
||||
$user = User::where('username', $item["username"])->first();
|
||||
if ($user) {
|
||||
|
@ -193,6 +199,9 @@ class LdapSync extends Command
|
|||
$user->username = $item["username"];
|
||||
$user->email = $item["email"];
|
||||
$user->employee_num = e($item["employee_number"]);
|
||||
$user->phone = $item["telephone"];
|
||||
$user->jobtitle = $item["jobtitle"];
|
||||
$user->country = $item["country"];
|
||||
|
||||
// Sync activated state for Active Directory.
|
||||
if ( array_key_exists('useraccountcontrol', $results[$i]) ) {
|
||||
|
|
|
@ -5,8 +5,8 @@ use Illuminate\Console\Command;
|
|||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
|
||||
ini_set('max_execution_time', env('IMPORT_TIME_LIM', 600)); //600 seconds = 10 minutes
|
||||
ini_set('memory_limit', env('IMPORT_MEM_LIM', '500M'));
|
||||
ini_set('max_execution_time', env('IMPORT_TIME_LIMIT', 600)); //600 seconds = 10 minutes
|
||||
ini_set('memory_limit', env('IMPORT_MEMORY_LIMIT', '500M'));
|
||||
|
||||
/**
|
||||
* Class ObjectImportCommand
|
||||
|
|
|
@ -1002,38 +1002,38 @@ class Helper
|
|||
* @return string path to uploaded image or false if something went wrong
|
||||
*/
|
||||
public static function processUploadedImage(String $image_data, String $save_path) {
|
||||
if ($image_data != null && $save_path != null) {
|
||||
// After modification, the image is prefixed by mime info like the following:
|
||||
// data:image/jpeg;base64,; This causes the image library to be unhappy, so we need to remove it.
|
||||
$header = explode(';', $image_data, 2)[0];
|
||||
// Grab the image type from the header while we're at it.
|
||||
$extension = substr($header, strpos($header, '/')+1);
|
||||
// Start reading the image after the first comma, postceding the base64.
|
||||
$image = substr($image_data, strpos($image_data, ',')+1);
|
||||
|
||||
$file_name = str_random(25).".".$extension;
|
||||
|
||||
$directory= public_path($save_path);
|
||||
// Check if the uploads directory exists. If not, try to create it.
|
||||
if (!file_exists($directory)) {
|
||||
mkdir($directory, 0755, true);
|
||||
}
|
||||
|
||||
$path = public_path($save_path.$file_name);
|
||||
|
||||
try {
|
||||
Image::make($image)->resize(500, 500, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $file_name;
|
||||
if ($image_data == null || $save_path == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
// After modification, the image is prefixed by mime info like the following:
|
||||
// data:image/jpeg;base64,; This causes the image library to be unhappy, so we need to remove it.
|
||||
$header = explode(';', $image_data, 2)[0];
|
||||
// Grab the image type from the header while we're at it.
|
||||
$extension = substr($header, strpos($header, '/')+1);
|
||||
// Start reading the image after the first comma, postceding the base64.
|
||||
$image = substr($image_data, strpos($image_data, ',')+1);
|
||||
|
||||
$file_name = str_random(25).".".$extension;
|
||||
|
||||
$directory= public_path($save_path);
|
||||
// Check if the uploads directory exists. If not, try to create it.
|
||||
if (!file_exists($directory)) {
|
||||
mkdir($directory, 0755, true);
|
||||
}
|
||||
|
||||
$path = public_path($save_path.$file_name);
|
||||
|
||||
try {
|
||||
Image::make($image)->resize(500, 500, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->save($path);
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $file_name;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -254,7 +254,8 @@ class AccessoriesController extends Controller
|
|||
'accessory_id' => $accessory->id,
|
||||
'created_at' => Carbon::now(),
|
||||
'user_id' => Auth::id(),
|
||||
'assigned_to' => $request->get('assigned_to')
|
||||
'assigned_to' => $request->get('assigned_to'),
|
||||
'note' => $request->get('note')
|
||||
]);
|
||||
|
||||
$accessory->logCheckout($request->input('note'), $user);
|
||||
|
|
|
@ -478,13 +478,36 @@ class AssetsController extends Controller
|
|||
$model = AssetModel::find($request->get('model_id'));
|
||||
if (($model) && ($model->fieldset)) {
|
||||
foreach ($model->fieldset->fields as $field) {
|
||||
if ($field->field_encrypted=='1') {
|
||||
if (Gate::allows('admin')) {
|
||||
$asset->{$field->convertUnicodeDbSlug()} = \Crypt::encrypt($request->input($field->convertUnicodeDbSlug()));
|
||||
}
|
||||
} else {
|
||||
$asset->{$field->convertUnicodeDbSlug()} = $request->input($field->convertUnicodeDbSlug());
|
||||
|
||||
// Set the field value based on what was sent in the request
|
||||
$field_val = $request->input($field->convertUnicodeDbSlug(), null);
|
||||
|
||||
// If input value is null, use custom field's default value
|
||||
if ($field_val == null) {
|
||||
\Log::debug('Field value for '.$field->convertUnicodeDbSlug().' is null');
|
||||
$field_val = $field->defaultValue($request->get('model_id'));
|
||||
\Log::debug('Use the default fieldset value of '.$field->defaultValue($request->get('model_id')));
|
||||
}
|
||||
|
||||
// if the field is set to encrypted, make sure we encrypt the value
|
||||
if ($field->field_encrypted == '1') {
|
||||
|
||||
\Log::debug('This model field is encrypted in this fieldset.');
|
||||
|
||||
if (Gate::allows('admin')) {
|
||||
|
||||
// If input value is null, use custom field's default value
|
||||
if (($field_val == null) && ($request->has('model_id')!='')){
|
||||
$field_val = \Crypt::encrypt($field->defaultValue($request->get('model_id')));
|
||||
} else {
|
||||
$field_val = \Crypt::encrypt($request->input($field->convertUnicodeDbSlug()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$asset->{$field->convertUnicodeDbSlug()} = $field_val;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
138
app/Http/Controllers/Api/LicenseSeatsController.php
Normal file
138
app/Http/Controllers/Api/LicenseSeatsController.php
Normal file
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Helpers\Helper;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Transformers\LicenseSeatsTransformer;
|
||||
use App\Models\Asset;
|
||||
use App\Models\License;
|
||||
use App\Models\LicenseSeat;
|
||||
use App\Models\User;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class LicenseSeatsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index(Request $request, $licenseId)
|
||||
{
|
||||
//
|
||||
if ($license = License::find($licenseId)) {
|
||||
$this->authorize('view', $license);
|
||||
|
||||
$seats = LicenseSeat::with('license', 'user', 'asset', 'user.department')
|
||||
->where('license_seats.license_id', $licenseId);
|
||||
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
|
||||
if ($request->input('sort')=='department') {
|
||||
$seats->OrderDepartments($order);
|
||||
} else {
|
||||
$seats->orderBy('id', $order);
|
||||
}
|
||||
|
||||
$total = $seats->count();
|
||||
$offset = (($seats) && (request('offset') > $total)) ? 0 : request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
|
||||
$seats = $seats->skip($offset)->take($limit)->get();
|
||||
|
||||
if ($seats) {
|
||||
return (new LicenseSeatsTransformer)->transformLicenseSeats($seats, $total);
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/licenses/message.does_not_exist')), 200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($licenseId, $seatId)
|
||||
{
|
||||
//
|
||||
$this->authorize('view', License::class);
|
||||
// sanity checks:
|
||||
// 1. does the license seat exist?
|
||||
if (!$licenseSeat = LicenseSeat::find($seatId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Seat not found'));
|
||||
}
|
||||
// 2. does the seat belong to the specified license?
|
||||
if (!$license = $licenseSeat->license()->first() || $license->id != intval($licenseId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Seat does not belong to the specified license'));
|
||||
}
|
||||
return (new LicenseSeatsTransformer)->transformLicenseSeat($licenseSeat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $licenseId
|
||||
* @param int $seatId
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $licenseId, $seatId)
|
||||
{
|
||||
$this->authorize('checkout', License::class);
|
||||
|
||||
// sanity checks:
|
||||
// 1. does the license seat exist?
|
||||
if (!$licenseSeat = LicenseSeat::find($seatId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Seat not found'));
|
||||
}
|
||||
// 2. does the seat belong to the specified license?
|
||||
if (!$license = $licenseSeat->license()->first() || $license->id != intval($licenseId)) {
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, 'Seat does not belong to the specified license'));
|
||||
}
|
||||
|
||||
$oldUser = $licenseSeat->user()->first();
|
||||
$oldAsset = $licenseSeat->asset()->first();
|
||||
|
||||
// attempt to update the license seat
|
||||
$licenseSeat->fill($request->all());
|
||||
$licenseSeat->user_id = Auth::user()->id;
|
||||
|
||||
// check if this update is a checkin operation
|
||||
// 1. are relevant fields touched at all?
|
||||
$touched = $licenseSeat->isDirty('assigned_to') || $licenseSeat->isDirty('asset_id');
|
||||
// 2. are they cleared? if yes then this is a checkin operation
|
||||
$is_checkin = ($touched && $licenseSeat->assigned_to === null && $licenseSeat->asset_id === null);
|
||||
|
||||
if (!$touched) {
|
||||
// nothing to update
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $licenseSeat, trans('admin/licenses/message.update.success')));
|
||||
}
|
||||
|
||||
if ($licenseSeat->save()) {
|
||||
// the logging functions expect only one "target". if both asset and user are present in the request,
|
||||
// we simply let assets take precedence over users...
|
||||
$changes = $licenseSeat->getChanges();
|
||||
if (array_key_exists('assigned_to', $changes)) {
|
||||
$target = $is_checkin ? $oldUser : User::find($changes['assigned_to']);
|
||||
}
|
||||
if (array_key_exists('asset_id', $changes)) {
|
||||
$target = $is_checkin ? $oldAsset : Asset::find($changes['asset_id']);
|
||||
}
|
||||
|
||||
if ($is_checkin) {
|
||||
$licenseSeat->logCheckin($target, $request->input('note'));
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $licenseSeat, trans('admin/licenses/message.update.success')));
|
||||
}
|
||||
|
||||
// in this case, relevant fields are touched but it's not a checkin operation. so it must be a checkout operation.
|
||||
$licenseSeat->logCheckout($request->input('note'), $target);
|
||||
return response()->json(Helper::formatStandardApiResponse('success', $licenseSeat, trans('admin/licenses/message.update.success')));
|
||||
}
|
||||
|
||||
return Helper::formatStandardApiResponse('error', null, $licenseSeat->getErrors());
|
||||
}
|
||||
}
|
|
@ -237,50 +237,6 @@ class LicensesController extends Controller
|
|||
}
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/licenses/message.assoc_users')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get license seat listing
|
||||
*
|
||||
* @author [A. Gianotto] [<snipe@snipe.net>]
|
||||
* @since [v1.0]
|
||||
* @param int $licenseId
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
public function seats(Request $request, $licenseId)
|
||||
{
|
||||
|
||||
if ($license = License::find($licenseId)) {
|
||||
|
||||
$this->authorize('view', $license);
|
||||
|
||||
$seats = LicenseSeat::with('license', 'user', 'asset', 'user.department')
|
||||
->where('license_seats.license_id', $licenseId);
|
||||
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
|
||||
if ($request->input('sort')=='department') {
|
||||
$seats->OrderDepartments($order);
|
||||
} else {
|
||||
$seats->orderBy('id', $order);
|
||||
}
|
||||
|
||||
$offset = (($seats) && (request('offset') > $seats->count())) ? 0 : request('offset', 0);
|
||||
$limit = request('limit', 50);
|
||||
|
||||
$total = $seats->count();
|
||||
|
||||
$seats = $seats->skip($offset)->take($limit)->get();
|
||||
|
||||
if ($seats) {
|
||||
return (new LicenseSeatsTransformer)->transformLicenseSeats($seats, $total);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return response()->json(Helper::formatStandardApiResponse('error', null, trans('admin/licenses/message.does_not_exist')), 200);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets a paginated collection for the select2 menus
|
||||
|
|
|
@ -484,7 +484,7 @@ class AssetsController extends Controller
|
|||
return response()->file($barcode_file, $header);
|
||||
} else {
|
||||
// Calculate barcode width in pixel based on label width (inch)
|
||||
$barcode_width = ($settings->labels_width - $settings->labels_display_sgutter) * 96.000000000001;
|
||||
$barcode_width = ($settings->labels_width - $settings->labels_display_sgutter) * 200.000000000001;
|
||||
|
||||
$barcode = new \Com\Tecnick\Barcode\Barcode();
|
||||
try {
|
||||
|
|
|
@ -210,5 +210,29 @@ class LocationsController extends Controller
|
|||
|
||||
return redirect()->route('locations.index')->with('error', trans('admin/locations/message.does_not_exist'));
|
||||
}
|
||||
|
||||
public function print_assigned($id)
|
||||
{
|
||||
|
||||
}
|
||||
$location = Location::where('id',$id)->first();
|
||||
$parent = Location::where('id',$location->parent_id)->first();
|
||||
$manager = User::where('id',$location->manager_id)->first();
|
||||
$users = User::where('location_id', $id)->with('company', 'department', 'location')->get();
|
||||
$assets = Asset::where('assigned_to', $id)->where('assigned_type', Location::class)->with('model', 'model.category')->get();
|
||||
return view('locations/print')->with('assets', $assets)->with('users',$users)->with('location', $location)->with('parent', $parent)->with('manager', $manager);
|
||||
|
||||
}
|
||||
|
||||
public function print_all_assigned($id)
|
||||
{
|
||||
|
||||
$location = Location::where('id',$id)->first();
|
||||
$parent = Location::where('id',$location->parent_id)->first();
|
||||
$manager = User::where('id',$location->manager_id)->first();
|
||||
$users = User::where('location_id', $id)->with('company', 'department', 'location')->get();
|
||||
$assets = Asset::where('location_id', $id)->with('model', 'model.category')->get();
|
||||
return view('locations/print')->with('assets', $assets)->with('users',$users)->with('location', $location)->with('parent', $parent)->with('manager', $manager);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -48,10 +48,9 @@ class ProfileController extends Controller
|
|||
$user->last_name = $request->input('last_name');
|
||||
$user->website = $request->input('website');
|
||||
$user->gravatar = $request->input('gravatar');
|
||||
$user->skin = $request->input('skin');
|
||||
$user->phone = $request->input('phone');
|
||||
|
||||
|
||||
|
||||
if (!config('app.lock_passwords')) {
|
||||
$user->locale = $request->input('locale', 'en');
|
||||
}
|
||||
|
|
|
@ -403,9 +403,7 @@ class ReportsController extends Controller
|
|||
*/
|
||||
public function postCustom(Request $request)
|
||||
{
|
||||
|
||||
|
||||
ini_set('max_execution_time', env('REPORT_TIME_LIM', 12000)); //12000 seconds = 200 minutes
|
||||
ini_set('max_execution_time', env('REPORT_TIME_LIMIT', 12000)); //12000 seconds = 200 minutes
|
||||
$this->authorize('reports.view');
|
||||
|
||||
|
||||
|
|
|
@ -400,6 +400,7 @@ class SettingsController extends Controller
|
|||
$setting->version_footer = $request->input('version_footer');
|
||||
$setting->footer_text = $request->input('footer_text');
|
||||
$setting->skin = $request->input('skin');
|
||||
$setting->allow_user_skin = $request->input('allow_user_skin');
|
||||
$setting->show_url_in_emails = $request->input('show_url_in_emails', '0');
|
||||
$setting->logo_print_assets = $request->input('logo_print_assets', '0');
|
||||
|
||||
|
@ -942,6 +943,9 @@ class SettingsController extends Controller
|
|||
$setting->ldap_tls = $request->input('ldap_tls', '0');
|
||||
$setting->ldap_pw_sync = $request->input('ldap_pw_sync', '0');
|
||||
$setting->custom_forgot_pass_url = $request->input('custom_forgot_pass_url');
|
||||
$setting->ldap_phone_field = $request->input('ldap_phone');
|
||||
$setting->ldap_jobtitle = $request->input('ldap_jobtitle');
|
||||
$setting->ldap_country = $request->input('ldap_country');
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -32,8 +32,9 @@ class ItemImportRequest extends FormRequest
|
|||
|
||||
public function import(Import $import)
|
||||
{
|
||||
ini_set('max_execution_time', env('IMPORT_TIME_LIM', 600)); //600 seconds = 10 minutes
|
||||
ini_set('memory_limit', env('IMPORT_MEM_LIM', '500M'));
|
||||
ini_set('max_execution_time', env('IMPORT_TIME_LIMIT', 600)); //600 seconds = 10 minutes
|
||||
ini_set('memory_limit', env('IMPORT_MEMORY_LIMIT', '500M'));
|
||||
|
||||
$filename = config('app.private_uploads') . '/imports/' . $import->file_path;
|
||||
$import->import_type = $this->input('import-type');
|
||||
$class = title_case($import->import_type);
|
||||
|
|
|
@ -20,12 +20,11 @@ class LicenseSeatsTransformer
|
|||
return (new DatatablesTransformer)->transformDatatables($array, $total);
|
||||
}
|
||||
|
||||
public function transformLicenseSeat (LicenseSeat $seat, $seat_count)
|
||||
public function transformLicenseSeat (LicenseSeat $seat, $seat_count=0)
|
||||
{
|
||||
$array = [
|
||||
'id' => (int) $seat->id,
|
||||
'license_id' => (int) $seat->license->id,
|
||||
'name' => 'Seat '.$seat_count,
|
||||
'assigned_user' => ($seat->user) ? [
|
||||
'id' => (int) $seat->user->id,
|
||||
'name'=> e($seat->user->present()->fullName),
|
||||
|
@ -49,6 +48,10 @@ class LicenseSeatsTransformer
|
|||
'user_can_checkout' => (($seat->assigned_to=='') && ($seat->asset_id=='')),
|
||||
];
|
||||
|
||||
if($seat_count != 0) {
|
||||
$array['name'] = 'Seat '.$seat_count;
|
||||
}
|
||||
|
||||
$permissions_array['available_actions'] = [
|
||||
'checkout' => Gate::allows('checkout', License::class),
|
||||
'checkin' => Gate::allows('checkin', License::class),
|
||||
|
|
|
@ -120,8 +120,10 @@ class AssetImporter extends ItemImporter
|
|||
$this->log('Asset ' . $this->item["name"] . ' with serial number ' . $this->item['serial'] . ' was created');
|
||||
|
||||
// If we have a target to checkout to, lets do so.
|
||||
//-- user_id is a property of the abstract class Importer, which this class inherits from and it's setted by
|
||||
//-- the class that needs to use it (command importer or GUI importer inside the project).
|
||||
if(isset($target)) {
|
||||
$asset->fresh()->checkOut($target);
|
||||
$asset->fresh()->checkOut($target, $this->user_id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -313,8 +313,14 @@ class Asset extends Depreciable
|
|||
}
|
||||
|
||||
if ($this->save()) {
|
||||
|
||||
event(new CheckoutableCheckedOut($this, $target, Auth::user(), $note));
|
||||
if (is_integer($admin)){
|
||||
$checkedOutBy = User::findOrFail($admin);
|
||||
} elseif (get_class($admin) === 'App\Models\User') {
|
||||
$checkedOutBy = $admin;
|
||||
} else {
|
||||
$checkedOutBy = Auth::user();
|
||||
}
|
||||
event(new CheckoutableCheckedOut($this, $target, $checkedOutBy, $note));
|
||||
|
||||
$this->increment('checkout_counter', 1);
|
||||
return true;
|
||||
|
|
|
@ -359,7 +359,7 @@ class CustomField extends Model
|
|||
"name" => "required|unique:custom_fields",
|
||||
"element" => [
|
||||
"required",
|
||||
Rule::in(['text', 'listbox', 'textara', 'checkbox', 'radio'])
|
||||
Rule::in(['text', 'listbox', 'textarea', 'checkbox', 'radio'])
|
||||
],
|
||||
'format' => [
|
||||
Rule::in(array_merge(array_keys(CustomField::PREDEFINED_FORMATS), CustomField::PREDEFINED_FORMATS))
|
||||
|
|
|
@ -169,7 +169,9 @@ class Ldap extends Model
|
|||
$ldap_result_last_name = Setting::getSettings()->ldap_lname_field;
|
||||
$ldap_result_first_name = Setting::getSettings()->ldap_fname_field;
|
||||
$ldap_result_email = Setting::getSettings()->ldap_email;
|
||||
|
||||
$ldap_result_phone = Setting::getSettings()->ldap_phone;
|
||||
$ldap_result_jobtitle = Setting::getSettings()->ldap_jobtitle;
|
||||
$ldap_result_country = Setting::getSettings()->ldap_country;
|
||||
// Get LDAP user data
|
||||
$item = array();
|
||||
$item["username"] = isset($ldapatttibutes[$ldap_result_username][0]) ? $ldapatttibutes[$ldap_result_username][0] : "";
|
||||
|
@ -177,7 +179,9 @@ class Ldap extends Model
|
|||
$item["lastname"] = isset($ldapatttibutes[$ldap_result_last_name][0]) ? $ldapatttibutes[$ldap_result_last_name][0] : "";
|
||||
$item["firstname"] = isset($ldapatttibutes[$ldap_result_first_name][0]) ? $ldapatttibutes[$ldap_result_first_name][0] : "";
|
||||
$item["email"] = isset($ldapatttibutes[$ldap_result_email][0]) ? $ldapatttibutes[$ldap_result_email][0] : "" ;
|
||||
|
||||
$item["telephone"] = isset($ldapatttibutes[$ldap_result_phone][0]) ?$ldapatttibutes[$ldap_result_phone][0] : "";
|
||||
$item["jobtitle"] = isset($ldapatttibutes[$ldap_result_jobtitle][0]) ? $ldapatttibutes[$ldap_result_jobtitle][0] : "";
|
||||
$item["country"] = isset($ldapatttibutes[$ldap_result_country][0]) ? $ldapatttibutes[$ldap_result_country][0] : "";
|
||||
return $item;
|
||||
|
||||
|
||||
|
|
|
@ -20,6 +20,16 @@ class LicenseSeat extends SnipeModel implements ICompanyableChild
|
|||
protected $guarded = 'id';
|
||||
protected $table = 'license_seats';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'assigned_to',
|
||||
'asset_id'
|
||||
];
|
||||
|
||||
use Acceptable;
|
||||
|
||||
public function getCompanyableParents()
|
||||
|
|
|
@ -114,20 +114,12 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
|||
|
||||
|
||||
/**
|
||||
* Check user permissions
|
||||
* Internally check the user permission for the given section
|
||||
*
|
||||
* Parses the user and group permission masks to see if the user
|
||||
* is authorized to do the thing
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @since [v1.0]
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasAccess($section)
|
||||
protected function checkPermissionSection($section)
|
||||
{
|
||||
if ($this->isSuperUser()) {
|
||||
return true;
|
||||
}
|
||||
$user_groups = $this->groups;
|
||||
|
||||
|
||||
|
@ -158,6 +150,24 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check user permissions
|
||||
*
|
||||
* Parses the user and group permission masks to see if the user
|
||||
* is authorized to do the thing
|
||||
*
|
||||
* @author A. Gianotto <snipe@snipe.net>
|
||||
* @since [v1.0]
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasAccess($section)
|
||||
{
|
||||
if ($this->isSuperUser()) {
|
||||
return true;
|
||||
}
|
||||
return $this->checkPermissionSection($section);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the user is a SuperUser
|
||||
*
|
||||
|
@ -167,23 +177,7 @@ class User extends SnipeModel implements AuthenticatableContract, AuthorizableCo
|
|||
*/
|
||||
public function isSuperUser()
|
||||
{
|
||||
if (!$user_permissions = json_decode($this->permissions, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ($this->groups as $user_group) {
|
||||
$group_permissions = json_decode($user_group->permissions, true);
|
||||
$group_array = (array)$group_permissions;
|
||||
if ((array_key_exists('superuser', $group_array)) && ($group_permissions['superuser']=='1')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ((array_key_exists('superuser', $user_permissions)) && ($user_permissions['superuser']=='1')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return $this->checkPermissionSection('superuser');
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -35,4 +35,14 @@ class LicensePolicy extends CheckoutablePermissionsPolicy
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can access files associated with licenses.
|
||||
*
|
||||
* @param \App\Models\User $user
|
||||
* @return mixed
|
||||
*/
|
||||
public function files(User $user)
|
||||
{
|
||||
return $user->hasAccess($this->columnName().'.files');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -115,6 +115,23 @@ class AssetModelPresenter extends Presenter
|
|||
"title" => trans('general.notes'),
|
||||
"visible" => false,
|
||||
],
|
||||
[
|
||||
"field" => "created_at",
|
||||
"searchable" => true,
|
||||
"sortable" => true,
|
||||
"visible" => false,
|
||||
"title" => trans('general.created_at'),
|
||||
"formatter" => "dateDisplayFormatter"
|
||||
],
|
||||
[
|
||||
"field" => "updated_at",
|
||||
"searchable" => true,
|
||||
"sortable" => true,
|
||||
"visible" => false,
|
||||
"title" => trans('general.updated_at'),
|
||||
"formatter" => "dateDisplayFormatter"
|
||||
],
|
||||
|
||||
];
|
||||
|
||||
|
||||
|
|
|
@ -79,7 +79,23 @@ class CategoryPresenter extends Presenter
|
|||
"title" => trans('table.actions'),
|
||||
"visible" => true,
|
||||
"formatter" => "categoriesActionsFormatter",
|
||||
]
|
||||
],
|
||||
[
|
||||
"field" => "created_at",
|
||||
"searchable" => true,
|
||||
"sortable" => true,
|
||||
"visible" => false,
|
||||
"title" => trans('general.created_at'),
|
||||
"formatter" => "dateDisplayFormatter"
|
||||
],
|
||||
[
|
||||
"field" => "updated_at",
|
||||
"searchable" => true,
|
||||
"sortable" => true,
|
||||
"visible" => false,
|
||||
"title" => trans('general.updated_at'),
|
||||
"formatter" => "dateDisplayFormatter"
|
||||
],
|
||||
];
|
||||
|
||||
return json_encode($layout);
|
||||
|
|
|
@ -16,6 +16,7 @@ use App\Observers\LicenseObserver;
|
|||
use App\Observers\SettingObserver;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Routing\UrlGenerator;
|
||||
|
||||
/**
|
||||
* This service provider handles setting the observers on models
|
||||
|
@ -33,8 +34,15 @@ class AppServiceProvider extends ServiceProvider
|
|||
* @since [v3.0]
|
||||
* @return void
|
||||
*/
|
||||
public function boot()
|
||||
public function boot(UrlGenerator $url)
|
||||
{
|
||||
if (env('APP_FORCE_TLS')) {
|
||||
if (strpos(env('APP_URL'), 'https') === 0) {
|
||||
$url->forceScheme('https');
|
||||
} else {
|
||||
\Log::warning("'APP_FORCE_TLS' is set to true, but 'APP_URL' does not start with 'https://'. Will not force TLS on connections.");
|
||||
}
|
||||
}
|
||||
Schema::defaultStringLength(191);
|
||||
Asset::observe(AssetObserver::class);
|
||||
Accessory::observe(AccessoryObserver::class);
|
||||
|
|
|
@ -129,7 +129,13 @@ class LdapAd extends LdapAdConfiguration
|
|||
$login_username = $username;
|
||||
}
|
||||
|
||||
if ($this->ldap->auth()->attempt($login_username, $password, true) === false) {
|
||||
if ($this->ldapConfig['username'] && $this->ldapConfig['password']) {
|
||||
$bind_as_user = false;
|
||||
} else {
|
||||
$bind_as_user = true;
|
||||
}
|
||||
|
||||
if ($this->ldap->auth()->attempt($login_username, $password, $bind_as_user) === false) {
|
||||
throw new Exception('Unable to validate user credentials!');
|
||||
}
|
||||
|
||||
|
|
|
@ -218,6 +218,12 @@ return array(
|
|||
'note' => '',
|
||||
'display' => true,
|
||||
),
|
||||
array(
|
||||
'permission' => 'licenses.files',
|
||||
'label' => 'View and Modify License Files',
|
||||
'note' => '',
|
||||
'display' => true,
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddUserSkinSetting extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
// Update the users table
|
||||
Schema::table('users', function ($table) {
|
||||
$table->string('skin')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
// Update the users table
|
||||
Schema::table('users', function ($table) {
|
||||
$table->dropColumn('skin');
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddSettingAllowUserSkin extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
// Update the users table
|
||||
Schema::table('settings', function ($table) {
|
||||
$table->boolean('allow_user_skin')->default(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
// Update the users table
|
||||
Schema::table('settings', function ($table) {
|
||||
$table->dropColumn('allow_user_skin');
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddsSeveralLdapFields extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('settings', function (Blueprint $table) {
|
||||
$table->string('ldap_phone_field')->after('ldap_email')->nullable();
|
||||
$table->string('ldap_jobtitle')->after('ldap_phone_field')->nullable();
|
||||
$table->string('ldap_country')->after('ldap_jobtitle')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
27707
package-lock.json
generated
27707
package-lock.json
generated
File diff suppressed because it is too large
Load diff
18
package.json
18
package.json
|
@ -2,12 +2,12 @@
|
|||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "npm run development",
|
||||
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"watch": "npm run development -- --watch",
|
||||
"watch-poll": "npm run watch -- --watch-poll",
|
||||
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"prod": "npm run production",
|
||||
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
|
@ -15,12 +15,12 @@
|
|||
"devDependencies": {
|
||||
"axios": "^0.20.0",
|
||||
"babel-preset-latest": "^6.24.1",
|
||||
"cross-env": "^5.0.5",
|
||||
"cross-env": "^7.0",
|
||||
"jquery": "^3.5.1",
|
||||
"laravel-mix": "2.1",
|
||||
"laravel-mix": "^5.0.1",
|
||||
"lodash": "^4.17.20",
|
||||
"vue": "2.4.4",
|
||||
"vue-loader": "^13.6.1",
|
||||
"vue-loader": "^15.9.6",
|
||||
"vue-template-compiler": "2.4.4"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -34,6 +34,7 @@
|
|||
"bootstrap-less": "^3.3.8",
|
||||
"bootstrap-table": "^1.18.0",
|
||||
"chart.js": "^2.9.4",
|
||||
"css-loader": "^3.6.0",
|
||||
"ekko-lightbox": "^5.1.1",
|
||||
"font-awesome": "^4.7.0",
|
||||
"icheck": "^1.0.2",
|
||||
|
@ -43,12 +44,13 @@
|
|||
"jquery-ui": "^1.12.1",
|
||||
"jquery-ui-bundle": "^1.12.1",
|
||||
"jquery.iframe-transport": "^1.0.0",
|
||||
"less": "github:less/less.js#efa6eb5306f28a7ef7e235d79ce854b780345591",
|
||||
"less": "^3.13.1",
|
||||
"less-loader": "^4.1.0",
|
||||
"list.js": "^1.5.0",
|
||||
"papaparse": "^4.3.3",
|
||||
"phantomjs": "^2.1.7",
|
||||
"select2": "4.0.13",
|
||||
"sheetjs": "^2.0.0",
|
||||
"tableexport.jquery.plugin": "^1.10.20",
|
||||
"tether": "^1.4.0",
|
||||
"vue-resource": "^1.3.3"
|
||||
|
|
BIN
public/css/build/signature-pad.min.css
vendored
BIN
public/css/build/signature-pad.min.css
vendored
Binary file not shown.
BIN
public/css/dist/signature-pad.min.css
vendored
Normal file
BIN
public/css/dist/signature-pad.min.css
vendored
Normal file
Binary file not shown.
|
@ -19,8 +19,8 @@
|
|||
"/css/dist/skins/skin-orange-dark.css": "/css/dist/skins/skin-orange-dark.css?id=b3d2ebfcb2541fa8e9ec",
|
||||
"/css/dist/skins/skin-orange.css": "/css/dist/skins/skin-orange.css?id=39eb843599c275696aed",
|
||||
"/css/dist/all.css": "/css/dist/all.css?id=199fdf677ce0dce6cef8",
|
||||
"/css/blue.png": "/css/blue.png?id=4c85d6a97173123bd14a",
|
||||
"/css/blue@2x.png": "/css/blue@2x.png?id=62c67c6a822439e8a4ac",
|
||||
"/css/blue.png": "/css/blue.png?id=e83a6c29e04fe851f212",
|
||||
"/css/blue@2x.png": "/css/blue@2x.png?id=51135dd4d24f88f5de0b",
|
||||
"/css/dist/skins/skin-green-dark.min.css": "/css/dist/skins/skin-green-dark.min.css?id=0d9935d834b39386a82e",
|
||||
"/css/dist/skins/skin-black-dark.min.css": "/css/dist/skins/skin-black-dark.min.css?id=97ec6f217441ac2f79ed",
|
||||
"/css/dist/skins/skin-blue-dark.min.css": "/css/dist/skins/skin-blue-dark.min.css?id=8f7aed152883df9c6f5e",
|
||||
|
@ -30,9 +30,9 @@
|
|||
"/css/dist/skins/skin-orange-dark.min.css": "/css/dist/skins/skin-orange-dark.min.css?id=b3d2ebfcb2541fa8e9ec",
|
||||
"/css/dist/skins/skin-contrast.min.css": "/css/dist/skins/skin-contrast.min.css?id=d7996d850e8bcdc4e167",
|
||||
"/css/dist/signature-pad.css": "/css/dist/signature-pad.css?id=6a89d3cd901305e66ced",
|
||||
"/css/build/signature-pad.min.css": "/css/build/signature-pad.min.css?id=d41d8cd98f00b204e980",
|
||||
"/css/dist/signature-pad.min.css": "/css/dist/signature-pad.min.css?id=6a89d3cd901305e66ced",
|
||||
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=1e77fde04b3f42432581",
|
||||
"/js/build/vendor.js": "/js/build/vendor.js?id=b93877b4a88a76e1b18b",
|
||||
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=58d95c93430f2ae33392",
|
||||
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=fd6e727609678bf04984",
|
||||
"/js/dist/all.js": "/js/dist/all.js?id=0efed60df4636f215a73"
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ return array(
|
|||
'country' => 'Country',
|
||||
'create' => 'Create Location',
|
||||
'update' => 'Update Location',
|
||||
'print_assigned' => 'Print Assigned',
|
||||
'print_all_assigned' => 'Print All Assigned',
|
||||
'name' => 'Location Name',
|
||||
'address' => 'Address',
|
||||
'zip' => 'Postal Code',
|
||||
|
|
|
@ -14,6 +14,8 @@ return array(
|
|||
'alerts_enabled' => 'Email Alerts Enabled',
|
||||
'alert_interval' => 'Expiring Alerts Threshold (in days)',
|
||||
'alert_inv_threshold' => 'Inventory Alert Threshold',
|
||||
'allow_user_skin' => 'Allow user skin',
|
||||
'allow_user_skin_help_text' => 'Checking this box will allow a user to change the site skin for himself.' ,
|
||||
'asset_ids' => 'Asset IDs',
|
||||
'audit_interval' => 'Audit Interval',
|
||||
'audit_interval_help' => 'If you are required to regularly physically audit your assets, enter the interval in months.',
|
||||
|
@ -72,6 +74,9 @@ return array(
|
|||
'ldap_tls' => 'Use TLS',
|
||||
'ldap_tls_help' => 'This should be checked only if you are running STARTTLS on your LDAP server. ',
|
||||
'ldap_uname' => 'LDAP Bind Username',
|
||||
'ldap_phone' => 'LDAP Telephone Number',
|
||||
'ldap_jobtitle' => 'LDAP Job Title',
|
||||
'ldap_country' => 'LDAP Country',
|
||||
'ldap_pword' => 'LDAP Bind Password',
|
||||
'ldap_basedn' => 'Base Bind DN',
|
||||
'ldap_filter' => 'LDAP Filter',
|
||||
|
|
|
@ -582,3 +582,34 @@ Form::macro('skin', function ($name = "skin", $selected = null, $class = null) {
|
|||
return $select;
|
||||
|
||||
});
|
||||
|
||||
Form::macro('user_skin', function ($name = "skin", $selected = null, $class = null) {
|
||||
|
||||
$formats = array(
|
||||
'' => 'Site Default',
|
||||
'blue' => 'Default Blue',
|
||||
'blue-dark' => 'Blue (Dark Mode)',
|
||||
'green' => 'Green Dark',
|
||||
'green-dark' => 'Green (Dark Mode)',
|
||||
'red' => 'Red Dark',
|
||||
'red-dark' => 'Red (Dark Mode)',
|
||||
'orange' => 'Orange Dark',
|
||||
'orange-dark' => 'Orange (Dark Mode)',
|
||||
'black' => 'Black',
|
||||
'black-dark' => 'Black (Dark Mode)',
|
||||
'purple' => 'Purple',
|
||||
'purple-dark' => 'Purple (Dark Mode)',
|
||||
'yellow' => 'Yellow',
|
||||
'yellow-dark' => 'Yellow (Dark Mode)',
|
||||
'contrast' => 'High Contrast',
|
||||
);
|
||||
|
||||
$select = '<select name="'.$name.'" class="'.$class.'" style="width: 250px">';
|
||||
foreach ($formats as $format => $label) {
|
||||
$select .= '<option value="'.$format.'"'.($selected == $format ? ' selected="selected"' : '').'>'.$label.'</option> '."\n";
|
||||
}
|
||||
|
||||
$select .= '</select>';
|
||||
return $select;
|
||||
|
||||
});
|
|
@ -11,7 +11,7 @@
|
|||
@section('content')
|
||||
|
||||
|
||||
<link rel="stylesheet" href="{{ url(mix('css/build/signature-pad.min.css')) }}">
|
||||
<link rel="stylesheet" href="{{ url(mix('css/dist/signature-pad.min.css')) }}">
|
||||
|
||||
<style>
|
||||
.form-horizontal .control-label, .form-horizontal .radio, .form-horizontal .checkbox, .form-horizontal .radio-inline, .form-horizontal .checkbox-inline {
|
||||
|
|
|
@ -58,6 +58,17 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
@if ($snipeSettings->allow_user_skin=='1')
|
||||
<!-- Skin -->
|
||||
<div class="form-group {{ $errors->has('skin') ? 'error' : '' }}">
|
||||
<label for="website" class="col-md-3 control-label">{{ Form::label('skin', trans('general.skin')) }}</label>
|
||||
<div class="col-md-8">
|
||||
{!! Form::user_skin('skin', Input::old('skin', $user->skin), 'select2') !!}
|
||||
{!! $errors->first('skin', '<span class="alert-msg">:message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<!-- Phone -->
|
||||
<div class="form-group {{ $errors->has('phone') ? 'has-error' : '' }}">
|
||||
<label class="col-md-3 control-label" for="phone">{{ trans('admin/users/table.phone') }}</label>
|
||||
|
@ -67,8 +78,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- Website URL -->
|
||||
<div class="form-group {{ $errors->has('website') ? ' has-error' : '' }}">
|
||||
<label for="website" class="col-md-3 control-label">{{ trans('general.website') }}</label>
|
||||
|
@ -114,8 +123,6 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Two factor opt in -->
|
||||
@if ($snipeSettings->two_factor_enabled=='1')
|
||||
<div class="form-group {{ $errors->has('avatar') ? 'has-error' : '' }}">
|
||||
|
|
|
@ -16,6 +16,34 @@
|
|||
}
|
||||
</style>
|
||||
|
||||
<div class="col-md-6">
|
||||
<div class="box box-default" id="audited-div" style="display: none">
|
||||
<div class="box-header with-border">
|
||||
<h2 class="box-title"> {{ trans('general.bulkaudit_status') }} (<span id="audit-counter">0</span> assets audited) </h2>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
|
||||
<table id="audited" class="table table-striped snipe-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ trans('general.asset_tag') }}</th>
|
||||
<th>{{ trans('general.bulkaudit_status') }}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
<tr id="audit-loader" style="display: none;">
|
||||
<td colspan="3">
|
||||
<i class="fa fa-spinner spin" aria-hidden="true"></i> Processing...
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
<div class="row">
|
||||
{{ Form::open(['method' => 'POST', 'class' => 'form-horizontal', 'role' => 'form', 'id' => 'audit-form' ]) }}
|
||||
|
|
|
@ -28,13 +28,13 @@
|
|||
</script>
|
||||
|
||||
{{-- stylesheets --}}
|
||||
|
||||
<link rel="stylesheet" href="{{ url(mix('css/dist/all.css')) }}">
|
||||
<link rel="stylesheet" href="{{ mix('css/dist/all.css') }}">
|
||||
@if (($snipeSettings) && ($snipeSettings->allow_user_skin==1) && Auth::check() && Auth::user()->present()->skin != '')
|
||||
<link rel="stylesheet" href="{{ mix('css/skins/skin-'.Auth::user()->present()->skin.'.min.css') }}">
|
||||
@elseif (($snipeSettings) && ($snipeSettings->skin!=''))
|
||||
<link rel="stylesheet" href="{{ url(mix('css/dist/skins/skin-'.($snipeSettings->skin!='' ? $snipeSettings->skin : 'blue').'.css')) }}">
|
||||
|
||||
|
||||
|
||||
{{-- page level css --}}
|
||||
@endif
|
||||
{{-- page level css --}}
|
||||
@stack('css')
|
||||
|
||||
|
||||
|
|
|
@ -31,7 +31,9 @@
|
|||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="#details" data-toggle="tab">Details</a></li>
|
||||
<li><a href="#seats" data-toggle="tab">{{ trans('admin/licenses/form.seats') }}</a></li>
|
||||
@can('files', $license)
|
||||
<li><a href="#uploads" data-toggle="tab">{{ trans('general.file_uploads') }}</a></li>
|
||||
@endcan
|
||||
<li><a href="#history" data-toggle="tab">{{ trans('admin/licenses/general.checkout_history') }}</a></li>
|
||||
<li class="pull-right"><a href="#" data-toggle="modal" data-target="#uploadFileModal"><i class="fa fa-paperclip" aria-hidden="true"></i> {{ trans('button.upload') }}</a></li>
|
||||
</ul>
|
||||
|
@ -350,7 +352,7 @@
|
|||
data-sort-order="asc"
|
||||
data-sort-name="name"
|
||||
class="table table-striped snipe-table"
|
||||
data-url="{{ route('api.license.seats', $license->id) }}"
|
||||
data-url="{{ route('api.licenses.seats.index', $license->id) }}"
|
||||
data-export-options='{
|
||||
"fileName": "export-seats-{{ str_slug($license->name) }}-{{ date('Y-m-d') }}",
|
||||
"ignoreColumn": ["actions","image","change","checkbox","checkincheckout","icon"]
|
||||
|
@ -364,6 +366,7 @@
|
|||
</div> <!--/.row-->
|
||||
</div> <!-- /.tab-pane -->
|
||||
|
||||
@can('files', $license)
|
||||
<div class="tab-pane" id="uploads">
|
||||
<div class="table-responsive">
|
||||
<table
|
||||
|
@ -447,6 +450,7 @@
|
|||
</table>
|
||||
</div>
|
||||
</div> <!-- /.tab-pane -->
|
||||
@endcan
|
||||
|
||||
<div class="tab-pane" id="history">
|
||||
<div class="row">
|
||||
|
|
188
resources/views/locations/print.blade.php
Normal file
188
resources/views/locations/print.blade.php
Normal file
|
@ -0,0 +1,188 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||||
<title>Assigned to {{ $location->present()->fullName() }} Location</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: "Arial, Helvetica", sans-serif;
|
||||
}
|
||||
table.inventory {
|
||||
border: solid #000;
|
||||
border-width: 1px 1px 1px 1px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@page {
|
||||
size: A4;
|
||||
}
|
||||
table.inventory th, table.inventory td {
|
||||
border: solid #000;
|
||||
border-width: 0 1px 1px 0;
|
||||
padding: 3px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.print-logo {
|
||||
max-height: 40px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@if ($snipeSettings->logo_print_assets=='1')
|
||||
@if ($snipeSettings->brand == '3')
|
||||
|
||||
<h3>
|
||||
@if ($snipeSettings->logo!='')
|
||||
<img class="print-logo" src="{{ url('/') }}/uploads/{{ $snipeSettings->logo }}">
|
||||
@endif
|
||||
{{ $snipeSettings->site_name }}
|
||||
</h3>
|
||||
@elseif ($snipeSettings->brand == '2')
|
||||
@if ($snipeSettings->logo!='')
|
||||
<img class="print-logo" src="{{ url('/') }}/uploads/{{ $snipeSettings->logo }}">
|
||||
@endif
|
||||
@else
|
||||
<h3>{{ $snipeSettings->site_name }}</h3>
|
||||
@endif
|
||||
@endif
|
||||
|
||||
<h2>Asset Management System</h2>
|
||||
<b>Assigned To:</b> {{ $location->present()->fullName() }}
|
||||
@if ($parent)
|
||||
{{ $parent->present()->fullName() }}
|
||||
@endif
|
||||
<br>
|
||||
@if ($manager)
|
||||
<b>Manager:</b> {{ $manager->present()->fullName() }}<br>
|
||||
@endif
|
||||
<b>Current Date:</b> {{ date("d/m/Y h:i:s A") }}<br><br>
|
||||
|
||||
@if ($users->count() > 0)
|
||||
@php
|
||||
$counter = 1;
|
||||
@endphp
|
||||
<table class="inventory">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="6">{{ trans('general.users') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 5px;"></th>
|
||||
<th style="width: 25%;">Company</th>
|
||||
<th style="width: 25%;">User Name</th>
|
||||
<th style="width: 10%;">Employee No.</th>
|
||||
<th style="width: 20%;">Department</th>
|
||||
<th style="width: 20%;">Location</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@foreach ($users as $user)
|
||||
|
||||
<tr>
|
||||
<td>{{ $counter }}</td>
|
||||
<td>{{ $user->company->name }}</td>
|
||||
<td>{{ $user->first_name }} {{ $user->last_name }}</td>
|
||||
<td>{{ $user->employee_num }}</td>
|
||||
<td>{{ $user->department->name }}</td>
|
||||
<td>{{ $user->location->name }}</td>
|
||||
</tr>
|
||||
@php
|
||||
$counter++
|
||||
@endphp
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
|
||||
|
||||
|
||||
@if ($assets->count() > 0)
|
||||
<br><br>
|
||||
<table class="inventory">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colspan="10">{{ trans('general.assets') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 20px;"></th>
|
||||
<th style="width: 10%;">Asset Tag</th>
|
||||
<th style="width: 10%;">Name</th>
|
||||
<th style="width: 10%;">Category</th>
|
||||
<th style="width: 10%;">Manufacturer</th>
|
||||
<th style="width: 15%;">Model</th>
|
||||
<th style="width: 15%;">Serial</th>
|
||||
<th style="width: 10%;">Location</th>
|
||||
<th style="width: 10%;">Checked Out</th>
|
||||
<th style="width: 10%;">Expected Checkin</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@php
|
||||
$counter = 1;
|
||||
@endphp
|
||||
|
||||
@foreach ($assets as $asset)
|
||||
|
||||
<tr>
|
||||
<td>{{ $counter }}</td>
|
||||
<td>{{ $asset->asset_tag }}</td>
|
||||
<td>{{ $asset->name }}</td>
|
||||
<td>{{ $asset->model->category->name }}</td>
|
||||
<td>{{ $asset->model->manufacturer->name }}</td>
|
||||
<td>{{ $asset->model->name }} {{ $asset->model->model_number }}</td>
|
||||
<td>{{ $asset->serial }}</td>
|
||||
<td>{{ $asset->location->name }}</td>
|
||||
<td>{{ $asset->last_checkout }}</td>
|
||||
<td>{{ $asset->expected_checkin }}</td>
|
||||
</tr>
|
||||
@php
|
||||
$counter++
|
||||
@endphp
|
||||
@endforeach
|
||||
</table>
|
||||
@endif
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Signed By (Asset Auditor):</td>
|
||||
<td>___________________________</td>
|
||||
<td></td>
|
||||
<td>Date:</td>
|
||||
<td>____________________</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Signed By (Finance Asset Auditor):</td>
|
||||
<td>____________________</td>
|
||||
<td></td>
|
||||
<td>Date:</td>
|
||||
<td>____________________</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<table>
|
||||
<tr>
|
||||
<td>Signed By (Location Manager):</td>
|
||||
<td>_______________________</td>
|
||||
<td></td>
|
||||
<td>Date:</td>
|
||||
<td>____________________</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -9,10 +9,6 @@
|
|||
@parent
|
||||
@stop
|
||||
|
||||
@section('header_right')
|
||||
<a href="{{ route('locations.edit', ['location' => $location->id]) }}" class="btn btn-sm btn-primary pull-right">{{ trans('admin/locations/table.update') }} </a>
|
||||
@stop
|
||||
|
||||
{{-- Page content --}}
|
||||
@section('content')
|
||||
|
||||
|
@ -158,18 +154,23 @@
|
|||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-md-12">
|
||||
<a href="{{ route('locations.edit', ['location' => $location->id]) }}" style="width: 50%;" class="btn btn-sm btn-primary pull-left">{{ trans('admin/locations/table.update') }} </a>
|
||||
</div>
|
||||
<div class="col-md-12" style="padding-top: 5px;">
|
||||
<a href="{{ route('locations.print_assigned', ['location' => $location->id]) }}" style="width: 50%;" class="btn btn-sm btn-default pull-left">{{ trans('admin/locations/table.print_assigned') }} </a>
|
||||
</div>
|
||||
<div class="col-md-12" style="padding-top: 5px;">
|
||||
<a href="{{ route('locations.print_all_assigned', ['location' => $location->id]) }}" style="width: 50%;" class="btn btn-sm btn-default pull-left">{{ trans('admin/locations/table.print_all_assigned') }} </a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@stop
|
||||
|
||||
@section('moar_scripts')
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
iconsPrefix: 'fa',
|
||||
cookie: true,
|
||||
cookieExpire: '2y',
|
||||
cookieIdTable: '{{ Route::currentRouteName() }}',
|
||||
mobileResponsive: true,
|
||||
maintainSelected: true,
|
||||
trimOnSearch: false,
|
||||
|
|
|
@ -150,7 +150,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Email format -->
|
||||
<!-- Skin -->
|
||||
<div class="form-group {{ $errors->has('skin') ? 'error' : '' }}">
|
||||
<div class="col-md-3">
|
||||
{{ Form::label('skin', trans('general.skin')) }}
|
||||
|
@ -161,6 +161,17 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Allow User Skin -->
|
||||
<div class="form-group">
|
||||
<div class="col-md-3">
|
||||
{{ Form::label('allow_user_skin', trans('admin/settings/general.allow_user_skin')) }}
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
{{ Form::checkbox('allow_user_skin', '1', old('allow_user_skin', $setting->allow_user_skin),array('class' => 'minimal')) }}
|
||||
{{ trans('general.yes') }}
|
||||
<p class="help-block">{{ trans('admin/settings/general.allow_user_skin_help_text') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Custom css -->
|
||||
<div class="form-group {{ $errors->has('custom_css') ? 'error' : '' }}">
|
||||
|
|
|
@ -355,7 +355,47 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- LDAP Phone -->
|
||||
<div class="form-group {{ $errors->has('ldap_phone') ? 'error' : '' }}">
|
||||
<div class="col-md-3">
|
||||
{{ Form::label('ldap_phone', trans('admin/settings/general.ldap_phone')) }}
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
{{ Form::text('ldap_phone', Request::old('ldap_phone', $setting->ldap_phone_field), ['class' => 'form-control','placeholder' => 'telephonenumber', $setting->demoMode]) }}
|
||||
{!! $errors->first('ldap_phone', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
@if (config('app.lock_passwords')===true)
|
||||
<p class="text-warning"><i class="fa fa-lock" aria-hidden="true"></i> {{ trans('general.feature_disabled') }}</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- LDAP Job title -->
|
||||
<div class="form-group {{ $errors->has('ldap_jobtitle') ? 'error' : '' }}">
|
||||
<div class="col-md-3">
|
||||
{{ Form::label('ldap_jobtitle', trans('admin/settings/general.ldap_jobtitle')) }}
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
{{ Form::text('ldap_jobtitle', Request::old('ldap_jobtitle', $setting->ldap_jobtitle), ['class' => 'form-control','placeholder' => 'title', $setting->demoMode]) }}
|
||||
{!! $errors->first('ldap_jobtitle', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
@if (config('app.lock_passwords')===true)
|
||||
<p class="text-warning"><i class="fa fa-lock" aria-hidden="true"></i> {{ trans('general.feature_disabled') }}</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- LDAP Country -->
|
||||
<div class="form-group {{ $errors->has('ldap_country') ? 'error' : '' }}">
|
||||
<div class="col-md-3">
|
||||
{{ Form::label('ldap_country', trans('admin/settings/general.ldap_country')) }}
|
||||
</div>
|
||||
<div class="col-md-9">
|
||||
{{ Form::text('ldap_country', Request::old('ldap_country', $setting->ldap_country), ['class' => 'form-control','placeholder' => 'c', $setting->demoMode]) }}
|
||||
{!! $errors->first('ldap_country', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
@if (config('app.lock_passwords')===true)
|
||||
<p class="text-warning"><i class="fa fa-lock" aria-hidden="true"></i> {{ trans('general.feature_disabled') }}</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@if ($setting->ldap_enabled)
|
||||
|
||||
<!-- LDAP test -->
|
||||
|
|
|
@ -145,7 +145,7 @@
|
|||
@can('viewKeys', $license)
|
||||
{{ $license->serial }}
|
||||
@else
|
||||
------------
|
||||
<i class="fa-lock" aria-hidden="true"></i> {{ str_repeat('x', 15) }}
|
||||
@endcan
|
||||
</td>
|
||||
<td>{{ $license->assetlog->first()->created_at }}</td>
|
||||
|
|
|
@ -166,7 +166,6 @@ Route::group(['prefix' => 'v1','namespace' => 'Api', 'middleware' => 'auth:api']
|
|||
|
||||
/*--- Departments API ---*/
|
||||
|
||||
/*--- Suppliers API ---*/
|
||||
Route::group(['prefix' => 'departments'], function () {
|
||||
|
||||
|
||||
|
@ -496,11 +495,6 @@ Route::group(['prefix' => 'v1','namespace' => 'Api', 'middleware' => 'auth:api']
|
|||
/*--- Licenses API ---*/
|
||||
|
||||
Route::group(['prefix' => 'licenses'], function () {
|
||||
Route::get('{licenseId}/seats', [
|
||||
'as' => 'api.license.seats',
|
||||
'uses' => 'LicensesController@seats'
|
||||
]);
|
||||
|
||||
Route::get('selectlist',
|
||||
[
|
||||
'as' => 'api.licenses.selectlist',
|
||||
|
@ -525,7 +519,18 @@ Route::group(['prefix' => 'v1','namespace' => 'Api', 'middleware' => 'auth:api']
|
|||
]
|
||||
); // Licenses resource
|
||||
|
||||
|
||||
Route::resource('licenses.seats', 'LicenseSeatsController',
|
||||
[
|
||||
'names' =>
|
||||
[
|
||||
'index' => 'api.licenses.seats.index',
|
||||
'show' => 'api.licenses.seats.show',
|
||||
'update' => 'api.licenses.seats.update'
|
||||
],
|
||||
'except' => ['create', 'edit', 'destroy', 'store'],
|
||||
'parameters' => ['licenseseat' => 'licenseseat_id']
|
||||
]
|
||||
); // Licenseseats resource
|
||||
|
||||
/*--- Locations API ---*/
|
||||
|
||||
|
|
|
@ -22,6 +22,16 @@ Route::group(['middleware' => 'auth'], function () {
|
|||
Route::resource('locations', 'LocationsController', [
|
||||
'parameters' => ['location' => 'location_id']
|
||||
]);
|
||||
|
||||
Route::get(
|
||||
'locations/{locationId}/printassigned',
|
||||
[ 'as' => 'locations.print_assigned', 'uses' => 'LocationsController@print_assigned' ]
|
||||
);
|
||||
|
||||
Route::get(
|
||||
'locations/{locationId}/printallassigned',
|
||||
[ 'as' => 'locations.print_all_assigned', 'uses' => 'LocationsController@print_all_assigned' ]
|
||||
);
|
||||
|
||||
/*
|
||||
* Manufacturers
|
||||
|
|
55
snipeit.sh
55
snipeit.sh
|
@ -156,8 +156,8 @@ create_virtualhost () {
|
|||
create_user () {
|
||||
echo "* Creating Snipe-IT user."
|
||||
|
||||
if [ "$distro" == "ubuntu" ] || [ "$distro" == "debian" ] || [ "$distro" == "raspbian" ] ; then
|
||||
adduser --quiet --disabled-password --gecos '""' "$APP_USER"
|
||||
if [[ "$distro" == "ubuntu" ]] || [[ "$distro" == "debian" ]] || [[ "$distro" == "raspbian" ]] ; then
|
||||
adduser --quiet --disabled-password --gecos 'Snipe-IT User' "$APP_USER"
|
||||
else
|
||||
adduser "$APP_USER"
|
||||
fi
|
||||
|
@ -265,7 +265,13 @@ set_hosts () {
|
|||
echo >> /etc/hosts "127.0.0.1 $(hostname) $fqdn"
|
||||
}
|
||||
|
||||
if [[ -f /etc/lsb-release || -f /etc/debian_version ]]; then
|
||||
rename_default_vhost () {
|
||||
log "mv /etc/apache2/sites-enabled/000-default.conf /etc/apache2/sites-enabled/111-default.conf"
|
||||
log "mv /etc/apache2/sites-enabled/snipeit.conf /etc/apache2/sites-enabled/000-snipeit.conf"
|
||||
}
|
||||
|
||||
|
||||
if [[ -f /etc/debian_version || -f /etc/lsb-release ]]; then
|
||||
distro="$(lsb_release -is)"
|
||||
version="$(lsb_release -rs)"
|
||||
codename="$(lsb_release -cs)"
|
||||
|
@ -311,7 +317,7 @@ case $distro in
|
|||
apache_group=www-data
|
||||
apachefile=/etc/apache2/sites-available/$APP_NAME.conf
|
||||
;;
|
||||
*debian*)
|
||||
*Debian|debian*)
|
||||
echo " The installer has detected $distro version $version codename $codename."
|
||||
distro=debian
|
||||
apache_group=www-data
|
||||
|
@ -330,7 +336,7 @@ case $distro in
|
|||
apachefile=/etc/httpd/conf.d/$APP_NAME.conf
|
||||
;;
|
||||
*)
|
||||
echo " The installer was unable to determine your OS. Exiting for safety."
|
||||
echo " The installer was unable to determine your OS. Exiting for safety. Exiting for safety."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
@ -368,7 +374,39 @@ done
|
|||
|
||||
case $distro in
|
||||
debian)
|
||||
if [[ "$version" =~ ^9 ]]; then
|
||||
if [[ "$version" =~ ^10 ]]; then
|
||||
# Install for Debian 10.x
|
||||
tzone=$(cat /etc/timezone)
|
||||
|
||||
echo "* Adding PHP repository."
|
||||
log "apt-get install -y apt-transport-https lsb-release ca-certificates"
|
||||
log "wget -O /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg"
|
||||
echo "deb https://packages.sury.org/php/ $codename main" > /etc/apt/sources.list.d/php.list
|
||||
|
||||
echo -n "* Updating installed packages."
|
||||
log "apt-get update && apt-get -y upgrade" & pid=$!
|
||||
progress
|
||||
|
||||
echo "* Installing Apache httpd, PHP, MariaDB and other requirements."
|
||||
PACKAGES="mariadb-server mariadb-client apache2 libapache2-mod-php7.3 php7.3 php7.3-mcrypt php7.3-curl php7.3-mysql php7.3-gd php7.3-ldap php7.3-zip php7.3-mbstring php7.3-xml php7.3-bcmath curl git unzip"
|
||||
install_packages
|
||||
|
||||
echo "* Configuring Apache."
|
||||
create_virtualhost
|
||||
log "a2enmod rewrite"
|
||||
log "a2ensite $APP_NAME.conf"
|
||||
rename_default_vhost
|
||||
|
||||
set_hosts
|
||||
|
||||
echo "* Securing MariaDB."
|
||||
/usr/bin/mysql_secure_installation
|
||||
|
||||
install_snipeit
|
||||
|
||||
echo "* Restarting Apache httpd."
|
||||
log "service apache2 restart"
|
||||
elif [[ "$version" =~ ^9 ]]; then
|
||||
# Install for Debian 9.x
|
||||
tzone=$(cat /etc/timezone)
|
||||
|
||||
|
@ -389,6 +427,7 @@ case $distro in
|
|||
create_virtualhost
|
||||
log "a2enmod rewrite"
|
||||
log "a2ensite $APP_NAME.conf"
|
||||
rename_default_vhost
|
||||
|
||||
set_hosts
|
||||
|
||||
|
@ -422,6 +461,7 @@ case $distro in
|
|||
create_virtualhost
|
||||
log "a2enmod rewrite"
|
||||
log "a2ensite $APP_NAME.conf"
|
||||
rename_default_vhost
|
||||
|
||||
set_hosts
|
||||
|
||||
|
@ -456,8 +496,7 @@ case $distro in
|
|||
log "phpenmod mbstring"
|
||||
log "a2enmod rewrite"
|
||||
log "a2ensite $APP_NAME.conf"
|
||||
log "mv /etc/apache2/sites-enabled/000-default.conf /etc/apache2/sites-enabled/111-default.conf"
|
||||
log "mv /etc/apache2/sites-enabled/snipeit.conf /etc/apache2/sites-enabled/000-snipeit.conf"
|
||||
rename_default_vhost
|
||||
|
||||
set_hosts
|
||||
|
||||
|
|
185
tests/api/ApiLicenseSeatsCest.php
Normal file
185
tests/api/ApiLicenseSeatsCest.php
Normal file
|
@ -0,0 +1,185 @@
|
|||
<?php
|
||||
|
||||
use App\Http\Transformers\LicenseSeatsTransformer;
|
||||
use App\Models\Asset;
|
||||
use App\Models\License;
|
||||
use App\Models\LicenseSeat;
|
||||
use App\Models\User;
|
||||
|
||||
class ApiLicenseSeatsCest
|
||||
{
|
||||
protected $license;
|
||||
protected $timeFormat;
|
||||
|
||||
public function _before(ApiTester $I)
|
||||
{
|
||||
$this->user = \App\Models\User::find(1);
|
||||
$I->haveHttpHeader('Accept', 'application/json');
|
||||
$I->amBearerAuthenticated($I->getToken($this->user));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function indexLicenseSeats(ApiTester $I)
|
||||
{
|
||||
$I->wantTo('Get a list of license seats for a specific license');
|
||||
|
||||
// call
|
||||
$I->sendGET('/licenses/1/seats?limit=10&order=desc');
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
|
||||
// sample verify
|
||||
$licenseSeats = App\Models\LicenseSeat::where('license_id', 1)
|
||||
->orderBy('id','desc')->take(10)->get();
|
||||
// pick a random seat
|
||||
$licenseSeat = $licenseSeats->random();
|
||||
// need the index in the original list so that the "name" field is determined correctly
|
||||
$licenseSeatNumber = 0;
|
||||
foreach($licenseSeats as $index=>$seat) {
|
||||
if ($licenseSeat === $seat) {
|
||||
$licenseSeatNumber = $index+1;
|
||||
}
|
||||
}
|
||||
$I->seeResponseContainsJson($I->removeTimestamps((new LicenseSeatsTransformer)->transformLicenseSeat($licenseSeat, $licenseSeatNumber)));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function showLicenseSeat(ApiTester $I)
|
||||
{
|
||||
$I->wantTo('Get a license seat');
|
||||
|
||||
// call
|
||||
$I->sendGET('/licenses/1/seats/10');
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
|
||||
// sample verify
|
||||
$licenseSeat = App\Models\LicenseSeat::findOrFail(10);
|
||||
$I->seeResponseContainsJson($I->removeTimestamps((new LicenseSeatsTransformer)->transformLicenseSeat($licenseSeat)));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function checkoutLicenseSeatToUser(ApiTester $I)
|
||||
{
|
||||
$I->wantTo('Checkout a license seat to a user');
|
||||
|
||||
$user = App\Models\User::all()->random();
|
||||
$licenseSeat = App\Models\LicenseSeat::all()->random();
|
||||
$endpoint = '/licenses/'.$licenseSeat->license_id.'/seats/'.$licenseSeat->id;
|
||||
|
||||
$data = [
|
||||
'assigned_to' => $user->id,
|
||||
'note' => 'Test Checkout to User via API'
|
||||
];
|
||||
|
||||
// update
|
||||
$I->sendPATCH($endpoint, $data);
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
|
||||
$response = json_decode($I->grabResponse());
|
||||
$I->assertEquals('success', $response->status);
|
||||
$I->assertEquals(trans('admin/licenses/message.update.success'), $response->messages);
|
||||
$I->assertEquals($licenseSeat->license_id, $response->payload->license_id); // license id does not change
|
||||
$I->assertEquals($licenseSeat->id, $response->payload->id); // license seat id does not change
|
||||
|
||||
// verify
|
||||
$licenseSeat = $licenseSeat->fresh();
|
||||
$I->sendGET($endpoint);
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
$I->seeResponseContainsJson($I->removeTimestamps((new LicenseSeatsTransformer)->transformLicenseSeat($licenseSeat)));
|
||||
|
||||
// verify that the last logged action is a checkout
|
||||
$I->sendGET('/reports/activity?item_type=license&limit=1&item_id='.$licenseSeat->license_id);
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
$I->seeResponseContainsJson([
|
||||
"action_type" => "checkout"
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function checkoutLicenseSeatToAsset(ApiTester $I)
|
||||
{
|
||||
$I->wantTo('Checkout a license seat to an asset');
|
||||
|
||||
$asset = App\Models\Asset::all()->random();
|
||||
$licenseSeat = App\Models\LicenseSeat::all()->random();
|
||||
$endpoint = '/licenses/'.$licenseSeat->license_id.'/seats/'.$licenseSeat->id;
|
||||
|
||||
$data = [
|
||||
'asset_id' => $asset->id,
|
||||
'note' => 'Test Checkout to Asset via API'
|
||||
];
|
||||
|
||||
// update
|
||||
$I->sendPATCH($endpoint, $data);
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
|
||||
$response = json_decode($I->grabResponse());
|
||||
$I->assertEquals('success', $response->status);
|
||||
$I->assertEquals(trans('admin/licenses/message.update.success'), $response->messages);
|
||||
$I->assertEquals($licenseSeat->license_id, $response->payload->license_id); // license id does not change
|
||||
$I->assertEquals($licenseSeat->id, $response->payload->id); // license seat id does not change
|
||||
|
||||
// verify
|
||||
$licenseSeat = $licenseSeat->fresh();
|
||||
$I->sendGET($endpoint);
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
$I->seeResponseContainsJson($I->removeTimestamps((new LicenseSeatsTransformer)->transformLicenseSeat($licenseSeat)));
|
||||
|
||||
// verify that the last logged action is a checkout
|
||||
$I->sendGET('/reports/activity?item_type=license&limit=1&item_id='.$licenseSeat->license_id);
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
$I->seeResponseContainsJson([
|
||||
"action_type" => "checkout"
|
||||
]);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function checkoutLicenseSeatToUserAndAsset(ApiTester $I)
|
||||
{
|
||||
$I->wantTo('Checkout a license seat to a user AND an asset');
|
||||
|
||||
$asset = App\Models\Asset::all()->random();
|
||||
$user = App\Models\User::all()->random();
|
||||
$licenseSeat = App\Models\LicenseSeat::all()->random();
|
||||
$endpoint = '/licenses/'.$licenseSeat->license_id.'/seats/'.$licenseSeat->id;
|
||||
|
||||
$data = [
|
||||
'asset_id' => $asset->id,
|
||||
'assigned_to' => $user->id,
|
||||
'note' => 'Test Checkout to User and Asset via API'
|
||||
];
|
||||
|
||||
// update
|
||||
$I->sendPATCH($endpoint, $data);
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
|
||||
$response = json_decode($I->grabResponse());
|
||||
$I->assertEquals('success', $response->status);
|
||||
$I->assertEquals(trans('admin/licenses/message.update.success'), $response->messages);
|
||||
$I->assertEquals($licenseSeat->license_id, $response->payload->license_id); // license id does not change
|
||||
$I->assertEquals($licenseSeat->id, $response->payload->id); // license seat id does not change
|
||||
|
||||
// verify
|
||||
$licenseSeat = $licenseSeat->fresh();
|
||||
$I->sendGET($endpoint);
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
$I->seeResponseContainsJson($I->removeTimestamps((new LicenseSeatsTransformer)->transformLicenseSeat($licenseSeat)));
|
||||
|
||||
// verify that the last logged action is a checkout
|
||||
$I->sendGET('/reports/activity?item_type=license&limit=1&item_id='.$licenseSeat->license_id);
|
||||
$I->seeResponseIsJson();
|
||||
$I->seeResponseCodeIs(200);
|
||||
$I->seeResponseContainsJson([
|
||||
"action_type" => "checkout"
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
const { mix } = require('laravel-mix');
|
||||
const mix = require('laravel-mix');
|
||||
|
||||
// This generates a file called app.css, which we use
|
||||
// later on to build all.css
|
||||
|
@ -58,7 +57,7 @@ mix
|
|||
*/
|
||||
mix
|
||||
.copy('./resources/assets/css/signature-pad.css', './public/css/dist')
|
||||
.minify('./public/css/build/signature-pad.css');
|
||||
.minify('./public/css/dist/signature-pad.css');
|
||||
|
||||
// Combine main SnipeIT JS files
|
||||
mix.js(
|
||||
|
@ -94,8 +93,6 @@ mix.less('./resources/assets/less/skins/skin-orange.less', 'css/dist/skins', './
|
|||
mix.combine(
|
||||
[
|
||||
'./node_modules/bootstrap-table/dist/bootstrap-table.css',
|
||||
'./node_modules/bootstrap-table/dist/extentions/mobile/bootstrap-table-mobile.css',
|
||||
'./node_modules/bootstrap-table/dist/extensions/export/bootstrap-table-export.css',
|
||||
'./node_modules/bootstrap-table/dist/extensions/sticky-header/bootstrap-table-sticky-header.css'
|
||||
],
|
||||
'public/css/dist/bootstrap-table.css'
|
||||
|
@ -137,14 +134,14 @@ mix
|
|||
.combine(
|
||||
[
|
||||
'./node_modules/bootstrap-table/dist/bootstrap-table.js',
|
||||
'./node_modules/bootstrap-table/dist/extentions/mobile/bootstrap-table-mobile.js',
|
||||
'./node_modules/bootstrap-table/dist/extensions/mobile/bootstrap-table-mobile.js',
|
||||
'./node_modules/bootstrap-table/dist/extensions/export/bootstrap-table-export.js',
|
||||
'./node_modules/bootstrap-table/dist/extensions/cookie/bootstrap-table-cookie.js',
|
||||
'./resources/assets/js/extensions/jquery.base64.js',
|
||||
'./node_modules/tableexport.jquery.plugin/tableExport.js',
|
||||
'./node_modules/tableexport.jquery.plugin/libs/jsPDF/jspdf.min.js',
|
||||
'./resources/js/FileSaver.min.js',
|
||||
'./resources/js/xlsx.core.min.js',
|
||||
'./resources/assets/js/FileSaver.min.js',
|
||||
'./node_modules/xlsx/dist/xlsx.core.min.js',
|
||||
'./node_modules/tableexport.jquery.plugin/libs/jsPDF-AutoTable/jspdf.plugin.autotable.js',
|
||||
'./node_modules/bootstrap-table/dist/extensions/sticky-header/bootstrap-table-sticky-header.js',
|
||||
'./node_modules/bootstrap-table/dist/extensions/toolbar/bootstrap-table-toolbar.js'
|
||||
|
|
Loading…
Reference in a new issue